bugfix> json > 投稿

ライフサイクルメソッドを使用してこれをどのように解析する必要がありますか?

{"blocks":[{
  "key":"33du7",
  "text":"Hello there!",
  "type":"unstyled",
  "depth":0,
  "inlineStyleRanges":[],
  "entityRanges":[],
  "data":{}}],
  "entityMap":{}
}

コンポーネントでテキストをレンダリングしたいのですが、なぜ未定義のエラーがスローされるのかわかりません。どうすればいいですか?

これは私のコンポーネントです:

class Blog extends Component{
constructor(props){
    super(props);
    this.blogContent = props.blogContent;
    this.blogId = props.blogId;
    this.handleRemoveBlog = this.handleRemoveBlog.bind(this);
    this.state = {
        blog__: '',
    };
}
handleRemoveBlog(blogId){
    this.props.removeBlog(blogId);
}

これは私のライフサイクルメソッドです。this.setStateを使用しますが、まず最初にコンソールで未定義になります。

  componentWillMount(){
      this.state.blog__ = JSON.parse(this.blogContent);
      console.log(this.state.blog__.text);    // this gives undefined     
  }

これがレンダリングパーツです。 データはFirebaseから取得されます。 そして、{this.blogcontent}は、前述のjson文字列を提供します。

render(props) {
    return(
        <div className = "blog header">
            <p>{this.blog__.text}</p>
        </div>
    );
}
 }
 Blog.proptypes = {
    blogContent: Proptypes.string
 }

回答 3 件
  • これは主に、このオブジェクトの取得元に依存します。ネットワーク経由で取得した場合、渡すのに最適な場所は componentDidMount です 。この理由は、代替ライフサイクルメソッド( componentWillMount )は、コンポーネントの再レンダリングを保証しません。非同期メソッドが実行を完了するのを待たずに、レンダリングメソッドに制御を渡すためです。したがって、 componentDidMount  新しい props としてすぐに  受信または state  変更されると、再レンダリングがトリガーされます。ただし、このオブジェクトがアプリケーション内からプルされた場合、可能性はありますが、 componentWillMount 内でプルされても正常に機能します 。これは、その操作がはるかに高速になり、新しい props を使用してrenderメソッドに制御が渡されるためです。 。 state を設定する場合は特に保証されません  プロセス内(設定状態も非同期であるため、必要なすべてのデータが受信される前に制御が残りのコードを実行する場合があります)。

    要するに、これを componentDidMount に渡す  レンダリング関数で、このプロップにアクセスする前に、それが存在することを確認してください。つまり、代わりに

    render() {
     return <div>{this.props.theObject.blocks[0].key}</div>
    }
    
    

    むしろする:

    render() {
     return <div>{this.props.theObject && this.props.theObject.blocks[0].key}</div>
    }
    
    

    これはあなたがそれをする方法です(axiosを使用してネットワーク経由でファイルを取得していると仮定)

    componentDidMount() {
       axios.get('url/to/the/file')
         .then(fileData => this.setState({
           data: fileData
         });
    }
    render() {
      // return whatever you want here and setting the inner html to what the state holds
    }
    
    

  • を使用して状態を変更しないでください

     this.state.blog__ = JSON.parse(this.blogContent);
    
    

    適切な方法は this.setState() を使用することです  方法:

     this.setState({blog__: JSON.parse(this.blogContent)})
    
    

    次に、コンポーネントが確実に再レンダリングされるように、メソッド shouldComponentUpdate() を使用します :

    shouldComponentUpdate(nextProps,nextState) {
        if(nextState != this.state) {
            this.forceUpdate()
        }
    }
    
    

    StateとLifecycleのドキュメントをご覧ください。

    その他のポイント: componentDidMount() を使用する   componentWillMount() の代わりに 、今後廃止される予定です。

    Atention: The setState()  非同期メソッドです。そのため、状態は即座に更新されません。

  • this.setState({}) を使用する  あなたの componentWillMount で  関数は代わりにデータを変数に割り当てます。また、 componentDidMount を使用することをお勧めします   componentWillMount の代わりに  将来廃止されるからです。

     componentDidMount(){
          let text = JSON.parse( this.blogContent );
          this.setState({blog__: text });     
      }
    
    

    編集:@brandNewコメントに従って、componentDidMountでsetStateのみを使用します

あなたの答え