2017-11-03 12 views
4

ReactJでコンポーネントをレンダリングする前に、いくつかの初期データをロードしようとしています。 このプロセスでは、Fluxアーキテクチャも使用しています。ここに私のcontainerです:ComponentWillMountの前にレンダリングが発生する

class MemoryApp extends React.Component { 
    constructor(props){ 
     super(props); 
     MemoryActions.getInit(); 
     this.state = {}; 

    } 

    componentWillMount(){ 
     MemoryStore.on("init",() => { 
      this.setState({ 
       memory: MemoryStore.getInit() 
      }); 
     }) 
    } 

    render(){ 
     return (
      <div> 
       <button type="button">Get Random Memory</button> 
       <h1>Memory App</h1> 
       <MemoryImage memory={this.state.memory}/> 
       <MemoryText memory={this.state.memory}/> 
      </div> 
     ); 
    } 
} 

ので、このファイルには、私はいくつかのデータを取得するAPIを呼び出すアクションgetInit()を呼び出しています。このデータが受信されると、initイベントがstoreによって放出される。

class MemoryStore extends EventEmitter { 

    getInit(){ 
     return this.memory_response; 
    } 

    initLoad(response){ 
     this.memory_response = response; 
     this.emit("init"); 
    } 

    handleActions(action){ 

     switch (action.type) { 
      case MemoryConstants.GET_INIT_RESPONSE:{ 
       this.initLoad(action.response); 
       break; 
      } 
      default:{ 
       return true; 
      } 
     } 
    } 

} 

const memoryStore = new MemoryStore(); 
dispatcher.register(memoryStore.handleActions.bind(memoryStore)); 
export default memoryStore; 

次に、あなたが見ることができるように、我々はcomponenWillMount()で、その後の状態を設定します。次に、コンポーネントをレンダリングします。コンポーネントの1つがimageです: インポートは私が設定する前にコンポーネントがレンダリングされているように私には見える

memory-image.js:10 {memory: undefined} 
memory-image.js:10 {memory: Array(1)} 

...

export default class MemoryImage extends React.Component{ 
    renderItems(){ 

     console.log(this.props); // ===> Here is my console.log 
     if (this.props.memory){ 
      return this.props.memory[0].description; 
     } else { 
      return "Nothing"; 
     } 
    } 

    renderImage(){ 
     if (this.props.memory){ 
      return this.props.memory[0].image; 
     } else { 
      return "Nothing"; 
     } 
    } 

    render(){ 
     return(
      <div> 
       <p>{this.renderItems()}</p> 
       <img style={{width:'200px'}} src={this.renderImage()} alt="none"/> 
      </div> 
     ); 
    } 
} 

そして、コンソールにログインした後に「反応」からリアクトcomponentWillMount()の状態です。私はこれを望んでいない、私は状態がcomponentWillMount()に設定された後にコンポーネントをレンダリングするだけです。何か案は?

MemoryStore.on("init",() => { 
    this.setState({ 
     memory: MemoryStore.getInit() 
    }); 
}) 

機能(イベントの前に)戻り、レンダリング:

答えて

2

はい、それは右の部品をマウントする前に、あなたは、単にイベントリスナーエン追加しているため、レンダリングされます。

最も簡単な解決策(IMO)は次のようになります。

あなたができる
getMemoryItems() { 
    if (this.state.memory) { 
     return <div> 
      <MemoryImage memory={this.state.memory}/> 
      <MemoryText memory={this.state.memory}/> 
     </div> 
    } 
} 

render(){ 
    return (
     <div> 
      <button type="button">Get Random Memory</button> 
      <h1>Memory App</h1> 
      { this.getMemoryItems() } 
     </div> 
    ); 
} 

か:

render(){ 
    return (
     <div> 
      <button type="button">Get Random Memory</button> 
      <h1>Memory App</h1> 
      { this.state.memory ? <MemoryImage memory={this.state.memory}/> : '' } 
      { this.state.memory ? <MemoryText memory={this.state.memory}/> : '' } 
     </div> 
    ); 
} 
1

の理由は、あなただけ呼び出されますされ、componentWillMountにイベントハンドラを登録していることですそのイベントがいつか将来起こるとき(つまりあなたのケースではinit)。 componentWillMountは単にそれを登録し、フローを続けるだけです(つまり、render関数などを呼び出す)。そのイベントが発生した場合にのみ、memory状態になります。

memory状態が使用可能になるまで、あなたが何をレンダリングしたくないのであれば、あなたは、単にこの

render(){ 
     if(!this.state.memory){ 
      // Just wait for the memory to be available 
      return null; 
     } 
     return (
      <div> 
       <button type="button">Get Random Memory</button> 
       <h1>Memory App</h1> 
       <MemoryImage memory={this.state.memory}/> 
       <MemoryText memory={this.state.memory}/> 
      </div> 
     ); 
    } 
ようにレンダリング中に条件を置くことができます
関連する問題