2016-03-23 36 views
11

mam składnik profilu, który jest ładowany przez reagują routerem (ścieżka = „profil /: nazwę użytkownika”), a składnikiem sama wygląda następująco:nieskończonej pętli podczas produkcji w componentWillReceiveProps

... 
import { fetchUser } from '../actions/user'; 

class Profile extends Component { 
    constructor(props) { 
    super(props); 
    } 
    componentDidMount() { 
    const { username } = this.props; 
    this.fetchUser(username); 
    } 
    componentWillReceiveProps(nextProps) { 
    const { username } = nextProps.params; 
    this.fetchUser(username); 
    } 
    fetchUser(username) { 
    const { dispatch } = this.props; 
    dispatch(fetchUser(username)); 
    } 
    render() {...} 
} 

export default connect((state, ownProps) => { 
    return { 
    username: ownProps.params.username, 
    isAuthenticated: state.auth.isAuthenticated 
    }; 
})(Profile); 

i działania fetchUser wygląda następująco (Redux-API-middleware):

function fetchUser(id) { 
    let token = localStorage.getItem('jwt'); 
    return { 
    [CALL_API]: { 
     endpoint: `http://localhost:3000/api/users/${id}`, 
     method: 'GET', 
     headers: { 'x-access-token': token }, 
     types: [FETCH_USER_REQUEST, FETCH_USER_SUCCESS, FETCH_USER_FAILURE] 
    } 
    } 
} 

powodem dodałem funkcję componentWillReceiveProps ma reagować, gdy zmienia URL do drugiego: login i załadować że profil użytkownika informacji. Na pierwszy rzut oka wszystko wydaje się działać, ale potem zauważyłem podczas debugowania, że ​​funkcja componentWillReceiveProps jest wywoływana w nieskończonej pętli i nie wiem dlaczego. Jeśli usunę składnik componentWillReceiveProps, to profil nie zostanie zaktualizowany przy użyciu nowej nazwy użytkownika, ale nie mam problemu z pętlami. Jakieś pomysły?

Odpowiedz

2

Tak więc powodem, dla którego element componentWillReceiveProps znajduje się w nieskończonej pętli, jest fakt, że ta funkcja jest wywoływana za każdym razem, gdy zmieniono rekwizyty i wywoływany jest fetchUser, który wywoła akcję, która zmieni rekwizyty.

Dodaj porównanie, aby sprawdzić, czy konkretne zmiany prop zobaczyć https://stackoverflow.com/a/36207102/2085190

+1

Teraz rozumiem. Reduktor dla FETCH_USER_SUCCESS przechowywał dane użytkownika som, z którymi łączył się mój komponent Profile (o których zapomniałem dodać do powyższego kodu podczas pisania pytania). Tak więc przepływ był componentWillReceiveProps -> dispatcher -> dane aktualizacji reduktora, z którym Profil łączy się -> componentWillReceiveProps jest wywoływany ponownie i wszystko zaczyna się od nowa. Myślę, że będę musiał przenieść kod zmiany trasy gdzie indziej, aby uniknąć tej pętli. Dzięki! – hazmah0

15

spróbuj dodać warunek do porównania rekwizyty. Jeśli twój komponent tego potrzebuje.

componentWillRecieveProps(nextProps){ 
if(nextProps.value !== this.props.value) 
    dispatch(action()) //do dispatch here 
} 
3

Jeśli masz reagować z niektórymi params trasy ścieżki jak profil/loginu, można po prostu porównywać props.location.pathname

componentWillReceiveProps(nextProps){  
    if(nextProps.location.pathname !== this.props.location.pathname){ 
      dispatch() 
     } 
}