2017-11-25 3 views
0

Ich versuche, eine Reaktion Messaging-App, wo die Kanal-Seite besteht eine Kanalleiste Channel.js (Parent Component) mit einem allgemeinen und zufälligen Kanal und eine Nachrichtenliste ChannelMessage.js (Child Component).reagieren Kind Komponente nicht aktualisiert nach Parent-Status geändert

Derzeit kann ich auf die Kanalleiste klicken und es ändert die URL und this.props.channelName, aber die untergeordnete Komponente zeigt den gleichen Text, unabhängig von Link geklickt. Ich glaube es ist, weil ComponentDidMount nicht in der untergeordneten Komponente aufgerufen wird. Wie würde ich die untergeordnete Komponente aktualisieren/neu rendern, um ComponentDidMount neu laden zu lassen?

Channel.js

export default class Channel extends React.Component { 
constructor(props) { 
    super(props); 
    this.state = { 
     channelName: 'general' 
    }; 
    this.handleSignOut = this.handleSignOut.bind(this); 
} 

... 

render() { 
    return (
     <div className="container"> 
      <div className="row"> 
       <div className="channel-list col-lg-2"> 
        <h2>Channels</h2> 
        <ul className="list-group"> 
         <li><Link to="/channel/general" 
          onClick={() => this.setState({ channelName: 'general' })}>General</Link></li> 
         <li><Link to="/channel/random" 
          onClick={() => this.setState({ channelName: 'random' })}>Random</Link></li> 
        </ul> 
        <div className="footer-segment"> 
         ... 
        </div> 
       </div> 
       <ChannelMessages channelName={this.state.channelName} /> 
      </div> 
     </div> 
    ); 
} 

ChannelMessages.js

export default class ChannelMessages extends React.Component { 
constructor(props) { 
    super(props); 
    this.state = { 
     channelName: this.props.channelName, 
     message: '', 
     messages: [], 
     textValue: '' 
    } 
    ... 
} 

componentWillReceiveProps(nextProps) { 
    this.setState({channelName: nextProps.channelName}) 
} 

componentDidMount() { 
    this.messageRef = firebase.database().ref('messages/' + this.state.channelName); 
    this.messageRef.limitToLast(500).on('value', (snapshot) => { 
     let messages = snapshot.val(); 
     if (messages !== null) { 
      let newMessages = []; 
      for (let message in messages) { 
       newMessages.push({ 
        author: { 
         displayName: messages[message].author.displayName, 
         photoURL: messages[message].author.photoURL, 
         uid: messages[message].author.uid 
        }, 
        body: messages[message].body, 
        createdAt: messages[message].createdAt, 
        id: message 
       }); 
      } 
      this.setState({ messages: newMessages, textValue: newMessages.body }); 
     } 
     console.log(this.state.textValue) 
    }); 
} 

componentWillUnmount() { 
    this.messageRef.off('value'); 
} 

handleSubmitMessage(event) { 
    event.preventDefault(); 
    let user = firebase.auth().currentUser; 
    this.messageRef.push().set({ 
     author: { 
      displayName: user.displayName, 
      photoURL: user.photoURL, 
      uid: user.uid 
     }, 
     body: this.state.message, 
     createdAt: firebase.database.ServerValue.TIMESTAMP 
    }); 
    this.setState({ message: '' }); 
} 

... 

render() { 
    return (...); 
} 

}

+0

Verwenden Sie die Methode componentWillreceiveProps, um die Lebenszyklusmethode zu aktualisieren. – stack26

Antwort

0

warum sind Sie nicht den channel direkt von den Requisiten? Sie verwenden das ComponentDidMount-Ereignis. Es läuft nur einmal. Wenn Sie den Firebase-Code immer dann ausführen möchten, wenn ein neuer Kanalname übergeben wird; extrahieren Sie die Abruflogikfunktion und führen Sie es in componentDidMount und componentDidUpate (hier überprüfen, ob es von der vorherigen anders)

ComponentDidMount läuft nur einmal - more here

ComponentDidUpdate läuft nicht auf Initialzündung - more here

export default class ChannelMessages extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      message: '', 
      messages: [], 
      textValue: '' 
     } 
     ... 
    } 

    componentDidMount() { 
     const {channelName} = this.props; 

     fetchFromDb(channelName); 
    } 

    componentDidUpdate(prevProps) { 
     if (prevProps.channelName !== this.props.channelName) { 
      fetchFromDb(this.props.channelName);    
     } 
    } 

    componentWillUnmount() { 
     this.messageRef.off('value'); 
    } 

    handleSubmitMessage(event) { 
     event.preventDefault(); 
     let user = firebase.auth().currentUser; 
     this.messageRef.push().set({ 
      author: { 
       displayName: user.displayName, 
       photoURL: user.photoURL, 
       uid: user.uid 
      }, 
      body: this.state.message, 
      createdAt: firebase.database.ServerValue.TIMESTAMP 
     }); 
     this.setState({ message: '' }); 
    } 

    ... 

    render() { 
     return (...); 
    } 
} 
Verwandte Themen