2017-01-11 12 views
6

Jestem nowy w React. Utknąłem na tym, naprawdę doceniam jakąś pomoc!Stan nie aktualizuje się podczas odbierania nowych rekwizytów (ReactJS)

Element macierzysty przekaże tablicę do tego komponentu potomnego. Kiedy I console.log (this.props.repairs) pokazuje mi tablicę 4. Próbuję zaktualizować this.state.sortedDataList, gdy tablica napraw jest przekazywana. Konsola.log (this.state) jest nadal pokazując sortedDataList jako pustą tablicę.

Co robię źle? Wielkie dzięki, doceń każdą pomoc.

class Repairs extends React.Component { 
    constructor(props) { 
    super(props); 

    this.state = { 
     sortedDataList: [] 
    }; 
    } 

    componentWillReceiveProps(nextProps) { 
    if(this.props != nextProps) { 
     this.setState({ 
     sortedDataList: this.props.repairs 
     }); 
    } 
    } 

    render() { 
    console.log(this.props); 
    console.log(this.state); 

    return (
     <div></div> 
    ); 
    } 
} 
+2

Odpowiedzi z Jayce444 i Shubham są poprawne. Dodam, że powinieneś naprawdę zdecydować, czy potrzebujesz stanu, aby reprezentować to, co chcesz pokazać na stronie, czy możesz ściśle używać rekwizytów. Posiadanie "czystych" komponentów funkcjonalnych reagentów (komponentów, które renderują tylko w oparciu o rekwizyty) jest zawsze dobrym celem. –

+0

Dlaczego ustawiasz podpórki do stwierdzenia? co dobrego dla ciebie robi? masz teraz cień tych samych danych przechowywanych w stanie, jak i rekwizytach. Aby dodać do tego rekwizyty są uważane za niezmienne znaczenie, których nie należy i nie powinno się zmieniać. ustawienie rekwizytów do takiego stanu powoduje, że twoje niezmienne dane są teraz zmienne, co jest wzorem Anti-Pattern i jest dużym nie, nie. Przeczytaj to, aby dowiedzieć się więcej http://stackoverflow.com/a/28785276/2733506 –

Odpowiedz

1

componentWillReceiveProps nie jest wywoływany przy pierwszym renderowaniu. To jest powód, że nie widać żadnych aktualizacji w stanie

Od React Docs:

. „Wywołuje się, gdy składnik odbiera nowe rekwizyty Metoda ta nie jest wywoływana dla początkowego render”

Jeśli chcesz wprowadzić zmianę tylko za pierwszym razem, możesz skorzystać z funkcji cyklu życia componentWillMount i zaktualizować stan. Po kolejnej zmianie zostanie wywołana funkcja componentWillReceiveProps.

class Repairs extends React.Component { 
 
    constructor(props) { 
 
    super(props); 
 

 
    this.state = { 
 
     sortedDataList: [] 
 
    }; 
 
    } 
 

 
    componentWillMount() { 
 
    
 
     this.setState({ 
 
     sortedDataList: this.props.repairs 
 
     },() => console.log(this.state.sortedDataList)); 
 
    
 
    } 
 
    componentWillReceiveProps(nextProps) { 
 
    if(this.props != nextProps) { 
 
     this.setState({ 
 
     sortedDataList: nextProps.repairs 
 
     }); 
 
    } 
 
    } 
 

 
    render() { 
 
    console.log("r",this.props); 
 
    console.log("r",this.state); 
 

 
    return (
 
     <div></div> 
 
    ); 
 
    } 
 
} 
 

 
class App extends React.Component { 
 
    render() { 
 
    var arr = ["1", "2", "3"]; 
 
    return (
 
     <div > 
 
     <Repairs repairs={arr}/> 
 
     </div> 
 
    ) 
 
    } 
 
} 
 
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script> 
 
<div id="app"></div>

+0

Dzięki za odpowiedź. Faktycznie, zauważyłem, kiedy pierwszy raz trafiłem na trasę, wszystkie pliki console.logs przechodzą jako initialState z pustą tablicą. Ale po tym, jak asynchroniczne wywołania wysyłają rekwizyty do rodzica, a to zostaje przekazane i uderza w funkcję componentWillReceiveProps. Ale to sprawiło, że zakwestionowałem cykl życia i znalazłem swój głupi błąd. Powinien to być this.setState ({ sortedDataList: nextProps.repairs }); –

0

W konstruktora

this.state = { 
    sortedDataList: [] 
}; 

początkowo ustawiony stan na pustą tablicę, więc na pierwszy czyni to będzie pusta. Następnie, gdy rekwizyty zostaną zmienione, zostaną zaktualizowane za pomocą metody componentWillReceiveProps().

Jak powiedział Shubham, componentWillReceiveProps() nie jest wywoływana w pierwszym renderowaniu. Jeśli chcesz, aby odzwierciedlić stan rekwizyty prawo od pierwszego render, trzeba by umieścić go w konstruktorze tak:

this.state = { 
    sortedDataList: this.props.repair 
}; 
+2

przypisywanie rekwizytów do stanu początkowego jest anty wzorcem i nie powinniśmy tego przestrzegać. http://stackoverflow.com/questions/28785106/reactjs-why-is-passing-the-component-initial-state-a-prop-an-anti-pattern.Chociaż zgadzam się z tym, że jest to proste rozwiązanie, ale celowo nie wspomniałem o tym z powyższego powodu: –

+0

Ach, dobrze, punkt – Jayce444

4

Nieważne, że mój głupi błąd! Jeśli ktokolwiek inny utknie w tym w przyszłości ...

componentWillReceiveProps(nextProps) { 
    if(this.props != nextProps) { 
    this.setState({ 
     sortedDataList: nextProps.repairs 
    }); 
    } 
} 
+0

Podsumowując, problem jest setState został wywołany z obecnymi rekwizytami zamiast z następnymi rekwizytami. – Aaron

Powiązane problemy