2016-06-29 7 views
0

子どもが内部で登録できる親コンポーネントを持っているので、私はこのデータをどこか他の場所で使うことができます(例えば、メニューを生成する)。次のようにReact - 子と親の関係が小道

現在、私のコードは次のとおりです。

const app = document.getElementById('app'); 

class Children extends React.Component { 
    constructor(props) { 
    super(props); 
    } 

    componentWillMount() { 
    this.props.add(this.props.name); 
    } 

    render() { 
    return (
     <div>Children</div> 
    ) 
    } 
} 

class Items extends React.Component { 
    render() { 
    return (
     <nav> 
     {this.props.content} 
     </nav> 
    ) 
    } 
} 

class Parent extends React.Component { 
    constructor() { 
    super(); 

    this.state = { 
     sections: [] 
    } 
    } 

    add(section) { 
    const currentSections = this.state.sections; 
    const id = section.replace(' ', '-').toLowerCase(); 
    const obj = { name: section, id }; 

    this.setState({ 
     sections: currentSections.push(obj) 
    }); 
    } 

    render() { 
    console.log(this.state.sections); 
    return (
     <div> 
     <Items content={this.state.sections} /> 
     <Children add={this.add.bind(this)} name="Section 1" /> 
     <Children add={this.add.bind(this)} name="Section 2" /> 
     <Children add={this.add.bind(this)} name="Section 3" /> 
     </div> 
    ) 
    } 
} 

render(<Parent />, app); 

私の問題は3を返しthis.state.sections、ですが、私はcomponentDidMountで再度ログインしたときに、それが配列です。 どうすればいいですか?

JSBin

+0

わからない:これを緩和するために

、あなたはすべての3つが順次追加されることが保証されますsetStateを呼び出す別の方法を使用することができます配列。あなたの問題は何ですか? –

+0

問題は 'state.sections'は' render'ではなく、 'componentDidMount'の後の配列です。 'render'で' console.log(this.state.sections) 'を実行すると' 3'が得られます。 –

+0

ああ、私は参照してください。参考のためにjsbinを追加しました –

答えて

1
add(section) { 
    const currentSections = this.state.sections; 
    const id = section.replace(' ', '-').toLowerCase(); 
    const obj = { name: section, id }; 
currentSections.push(obj) 
    this.setState({ 
     sections: currentSections 
    }); 
    } 

理由は、あなたが実際にはカウントされませ配列を返しますcurrentSections.push(OBJ)に状態を設定してあります。先にプッシュしてセクションをcurrentSectionsに設定する

+0

偉大な、私はそれが小さいと知っていた;-)ありがとう! –

+1

実際には、インプレース変異はおそらく最良の選択肢ではありません。代わりに 'currentSections.concat([obj])'のようなものを使用して、新しい配列を返すと主張します。 –

+0

@GoshaArinichあなたが正しいです、私はこの例を例として使用していて、コンポーネント通信を学んでいます。 –

0

この問題は、pushを使用して新しい要素のインデックスを返すために発生しているようです。インプレース状態を変異さ

は最良の選択肢ではない、と私はそれが代わりにconcatを使用することをお勧めします主張:

{ 
    sections: currentSections.concat([obj]) 
} 

新しい配列を返しますどの。

具体的には、addコールの間に競合状態が発生する可能性があります.3つのコールバックがほぼ同時に呼び出されるため、currentSections[]になります。それぞれのアイテムはアイテムに追加されて設定され、最終的に状態は3つではなく1つの要素のみを含むようになります。私はstate.sections` *は*でなければなりません `...正しく、次のよ

this.setState(state => { 
    return { 
    sections: state.sections.concat([obj]) 
    }; 
}) 
+0

あなたの解決策も動作しますが、コンソールの警告が表示されます: 'Warning:flattenChildren(...):同じキーを持つ2人の子供、' section-1'が遭遇しました。子キーは一意でなければなりません。 2人の子供が鍵を共有すると、最初の子供だけが使用されます。 –