2017-01-02 9 views
0

こんにちは私は先週からリアクションを学んでいましたが、問題を解決しましたが、なぜ私の問題が解決されたのか理解しようとしています。ここでリアクションイベントリスナーと再取り付け

はコードの例です:

export default class ExampleComponent extends Component{ 

    constructor(...arg){ 
     super(...arg); 
     this.goToNextPage = this.goToNextPage.bind(this); 
     this.state = { currentPage: 1, 
         chapterImages: []}; 
    } 

    goToNextPage(){ 
     this.setState({ 
      ...this.state, 
      currentPage: R.inc(this.state.currentPage) 
     }); 
    } 

    render(){ 
     return (<button onClick={this.goToNextPage}>next</button>) 
    } 
} 

私はそのようなものを持っています。私は私のボタンをクリックしたときに私は、AJAX呼び出しを作ってるんだ、これが私のコンポーネントのアンマウントおよび再マウントの理由である私の実際のコードでは...最後に、私は次のエラーを取得する:

Warning: setState(...): Can only update a mounted or mounting component. 
This usually means you called setState() on an unmounted component. 
This is a no-op. 

しかし、私の場合コンストラクタからこの行をドロップ:

this.goToNextPage = this.goToNextPage.bind(this); 

そして、これにrenderメソッドで行を変更します。

return (<button onClick={this.goToNextPage.bind(this)}>next</button>) 

それは完璧に動作しますが、私は上記のエラーを取得し、なぜ私にはわからないのです。

コンポーネントがアンマウントされると、ボタンクリックリスナーにバインドされたメソッド「goToNextPage」の参照が保持されるため、私はそのルートに行きました。

バインドをコンストラクタに保持することによって、この問題を解決するにはどうすればよいですか?ここで

+0

コンポーネントがアンマウントされた理由は何ですか?おそらくより実践的なコード例が役に立つかもしれません。 btw、 'setState()'を使うときに状態をクローンする必要はなく、更新が必要なキーだけを渡します。 –

+0

onClickが呼び出された後、何らかの形でそのコンポーネントをアンマウントします。おそらく、コンポーネント自体の外にあるコードに関係していると思われます。私はそれがボタンだと思う、それはクリックで送信されるフォームですか? –

+0

私のコンポーネントがアンマウントされた理由は、私がajax呼び出しを行っているときに、ツリーコンポーネントのトップレベルにロードアイコンを表示するので、ツリーコンポーネントの下位レベルにある私のコンポーネントをアンマウントするからです私のコンポーネントがunmoutedで再マウントされている理由です。あなたの助けを借りてくれてありがとう。 –

答えて

0

は私の実際のコードのクラスです:

export default class MangaChapter extends Component{ 

    constructor(...arg){ 
    super(...arg); 
    this._getPageId = R.prop('pageId'); 
    this._getPages = R.prop('pages'); 
    this._generatePageMenuItem = (pageId) => (<MenuItem key={pageId} value={pageId} primaryText={`${pageId}`} />); 
    this._pageToMenuItem = R.compose(this._generatePageMenuItem, this._getPageId); 
    this._getMangaPageMenuItems = R.compose(R.map(this._pageToMenuItem), this._getPages); 
    this._toImageNode = (chapterPage) => (<img src={chapterPage.url} style={{display: 'block', margin: '0 auto'}}/>) 
    this._preloadImage = (chapterPage) => new Image().src = chapterPage.url; 
    this._preloadImages = R.forEach(this._preloadImage); 
    this._getImagePage = R.compose(R.map(this._toImageNode), this._preloadImages, this._getPages); 
    this.state = { currentPage: 1, chapterImages: this._getImagePage(this.props.chapter) }; 
    this.goToPreviousPage = this.goToPreviousPage.bind(this); 
    this.goToNextPage = this.goToNextPage.bind(this); 
    } 
    componentWillMount(){ 
    this.props.getChapter(this.props.params.mangaId, this.props.params.chapterNum); 
    } 

    componentWillUnmount(){ 
    console.log('UNMOUNT'); 
    } 

    componentWillReceiveProps(nextProps){ 
    const { chapter } = nextProps; 
    this.state = { currentPage: 1, chapterImages: this._getImagePage(chapter) }; 
    } 

    handleChange(event, index, currentPage){ 
    this.setState({currentPage}); 
    }; 

    goToPreviousPage(){ 
    this.setState({ 
     currentPage: R.dec(this.state.currentPage) 
    }); 
    } 

    goToNextPage(){ 
    this.setState({ 
     currentPage: R.inc(this.state.currentPage) 
    }); 
    } 

    displayPage(){ 
    return this.state.chapterImages[R.dec(this.state.currentPage)] 
    } 

    componentDidMount(){ 

    } 

    render(){ 
    const { chapter, loading } = this.props; 
    const chapterName = chapter.name; 
    const chapterNum = this.props.params.chapterNum; 

    if(loading) return (<CircularProgress size={80} thickness={5} style={loadingStyle} />); 

    return (
     <div> 
     <h2 style={{textAlign: 'center'}}>Chapter { chapterNum } : { chapterName } </h2> 
     <div> 
      {this.displayPage()} 
     </div> 
     <div> 
     <br/> 
      <Row style={{textAlign: 'center'}}> 
      <Col sm={4}> 
       <RaisedButton 
       label="Previous" 
       primary={true} 
       icon={<ChevronLeft />} 
       onClick={this.goToPreviousPage} 
       /> 
      </Col> 
      <Col sm={4}> 
       Page 
       <SelectField 
       value={""} 
       onChange={this.handleChange.bind(this)} 
       style={{width: '80px', display: 'inline-block'}} 
       value={this.state.currentPage} 
       > 
       {this._getMangaPageMenuItems(chapter)} 
       </SelectField> 
       of { chapter.pages.length } 
      </Col > 
      <Col sm={4}> 
       <RaisedButton 
       labelPosition="before" 
       label="Next" 
       primary={true} 
       icon={<ChevronRight />} 
       style = {{display: 'inline-block'}} 
       onClick={this.goToNextPage} 
       /> 
      </Col> 
      </Row> 
     </div> 
     </div> 
    ); 
    } 
} 

問題はコンストラクタでこれら二つの方法がある:私は置けば私はBU上記のようなエラーが出ることを行う場合

this.goToPreviousPage = this.goToPreviousPage.bind(this); 
    this.goToNextPage = this.goToNextPage.bind(this); 

これらのメソッドは、そのようなcomponentDidMountメソッドで:

componentDidMount(){ 
    this.goToPreviousPage = this.goToPreviousPage.bind(this); 
    this.goToNextPage = this.goToNextPage.bind(this); 
    } 

それは完全に動作します、あなたは知っていますか?

関連する問題