2016-02-11 10 views
21

otrzymuję następujące ostrzeżenieReact setstate można tylko zaktualizować zamontowany lub montażowy składnik

„Ostrzeżenie: setState (...): można aktualizować tylko montowane lub element montażowy zwykle oznacza to, że nazywa setState.() na niezmontowanym komponencie. To nie jest operacja. Sprawdź kod komponentu ContactPage. "

Kiedy pierwszy raz wchodzę na stronę kontaktu, wszystko jest w porządku. Jeśli przejdę poza stronę i wrócę, ostrzeżenie zostanie wyświetlone.

Kontakt Strona komponent:

import React, { Component, PropTypes } from 'react'; 
import AppStore from '../../stores/AppStore'; 
import AppActions from '../../actions/AppActions'; 
import DataContent from './DataContent'; 

const title = 'Contact Us'; 


class ContactPage extends Component { 

    constructor(props) { 
     super(props); 
     this.state = AppStore.getState(); 
     AppActions.getData(); 
    } 

    static contextTypes = { 
    onSetTitle: PropTypes.func.isRequired, 
    }; 

    componentWillMount() { 
    this.context.onSetTitle(title); 
    AppStore.listen(this.onChange.bind(this)); 
} 

componentWillUnmount() { 
    AppStore.unlisten(this.onChange.bind(this)); 
} 

onChange(state) { 
    this.setState(state); 
} 

renderData() { 
    return this.state.data.map((data) => { 
     return (
      <DataContent key={data.id} data={data} /> 
     ) 
    }) 
} 

    render() { 
    return (
     <div className={s.root}> 
     <div className={s.container}> 
      <h1>{title}</h1> 
      <div> 
       { this.renderData() } 
      </div> 
     </div> 
     </div> 
    ); 
} 

} 

export default ContactPage; 

Kiedy kładę debuggerów w dniu obciążenia stronie kontaktowej trafi componentWillMount(). Kiedy opuszczam stronę kontaktu, trafia ona componentWillUnmount(). Kiedy wracam do strony, ponownie uderza w componentWillMount(), a następnie zgłasza błąd, gdy trafi on w funkcję onChange (state).

Odpowiedz

36

Problem polega na tym, że detektor poprzedniej instancji składnika jest nadal zarejestrowany. A ponieważ poprzednia instancja nie jest już montowana, pojawia się ten błąd.

.bind zawsze zwraca funkcję nowa. Więc jeśli nie

AppStore.unlisten(this.onChange.bind(this)); 

następnie próbujesz usunąć słuchacza, który nie istnieje (co oczywiście nie powiedzie). Czyni nie usunąć słuchacza jesteś zarejestrowana AppStore.listen(this.onChange.bind(this))


Aby rozwiązać ten problem, należy wiązać handler raz w konstruktorze:

this.onChange = this.onChange.bind(this); 

a następnie użyć AppStore.listen(this.onChange) i AppStore.unlisten(this.onChange).

+0

to działało! Dzięki :) – erichardson30

+3

".bind zawsze zwraca nową funkcję" .... mind dmuchane !!! – CambridgeMike

+0

Dzięki za to. Zmagałem się z tym przez kilka godzin. – Avdept

6

Przed zmianą zamontowany jest komponent kontroli stanu.

render() { 
    return (
    <div ref="root" className={s.root}> 
     // ---- 
    </div> 
    )}; 

onChange(state) { 
    if(this.refs.root) { 
    this.setState(state); 
    } 
} 

Myślę, że to ci pomoże.

0

W twoim przypadku dodaj ref do root roota i sprawdź wartość ref przed wywołaniem setState.

Twój onChange metoda powinna wyglądać następująco:

onChange(state) { 
    this.refs.yourRef ? this.setState(state) : null;  
} 
-1

męczyłem się z tym problemem, jak również na dłuższą chwilę.

Rozwiązałem dla mnie propozycję @Felix Kling, ale również zadeklarowałem, że moja funkcja zwrotna została zadeklarowana w klasie składnika, w przeciwnym razie nie można użyć prefiksu this, co najwyraźniej było przyczyną mnie.

Oto przykład tego, co mam na myśli:

prawne, ale nie działa

function onChange() { 
    this.setState({ MyState: newState }) 
} 

class MyComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    onChange = onChange.bind(this); 
    } 

    componentDidMount() { 
    window.addEventListener('resize', onChange); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('resize', onChange); 
    } 

    render() { ... } 
} 

Works

class MyComponent extends React.Component { 
    constructor(props) { 
    super(props); 
    this.onChange = this.onChange.bind(this); 
    } 

    onChange() { 
    this.setState({ MyState: newState }) 
    } 

    componentDidMount() { 
    window.addEventListener('resize', this.onChange); 
    } 

    componentWillUnmount() { 
    window.removeEventListener('resize', this.onChange); 
    } 

    render() { ... } 
} 

Nadzieja pomaga ktoś e Z tym problemem. :)

Powiązane problemy