2017-04-25 14 views
3

私はこの単純なコンポーネントを持っています、initialPlayers小道具はAppコンポーネントに渡されます。反応中のコンポーネントに渡されるpropsから状態を設定するにはどうすればいいですか?

import React from 'react'; 
import ReactDOM from 'react-dom'; 

var PLAYERS = [ 
    { 
    name: "xyz", 
    score: 123 
    } 
]; 

// App component 
class App extends React.Component { 

constructor() { 
    super(); 
} 

componentDidMount() { 
    this.state = { 
    players: this.props.initialPlayers 
    } 
} 

render() {  
    return(
    <div> 
     <Header players={this.state.players} /> 
    </div> 
    ); 
} 
} 

// Render component 
ReactDOM.render(<App initialPlayers={ PLAYERS }/>, 
document.getElementById('root')); 

は、コンソールでこのエラーを有し、{this.state.players}としてHeaderコンポーネントに値を渡すことができません。何か案が?。

それは 前に、コンポーネントの最初のレンダリング実行されるため、あなたは componentWillMountを使用したい
Uncaught TypeError: Cannot read property 'players' of null 
at App.render (bundle.js:14379) 
at bundle.js:20173 
at measureLifeCyclePerf (bundle.js:19452) 
at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (bundle.js:20172) 
at ReactCompositeComponentWrapper._renderValidatedComponent (bundle.js:20199) 
at ReactCompositeComponentWrapper.performInitialMount (bundle.js:19739) 
at ReactCompositeComponentWrapper.mountComponent (bundle.js:19635) 
at Object.mountComponent (bundle.js:4667) 
at ReactCompositeComponentWrapper.performInitialMount (bundle.js:19748) 
at ReactCompositeComponentWrapper.mountComponent (bundle.js:19635) 
+0

可能性のある重複した[コンポーネントは小道具から状態を初期化リアクト](https://stackoverflow.com/questions/40063468/react-component-initialize-state-from-props) – jalal246

答えて

2

移動(これは反応でstateを更新するための推奨される方法です)、それを変更するには:の

constructor(props) { 
    super(props); 
    this.state = { 
    players: this.props.initialPlayers 
    }; 
} 
+0

です。これは、Facebookがそのドキュメントに示したとおりです:https://reactjs.org/docs/react-component.html#constructor – Rohmer

1

からcomponentDidMount

var PLAYERS = [ 
 
    { name: "xyz", score: 123 }, 
 
    { name: 'abc', score: 111 }, 
 
    { name: 'def', score: 222 } 
 
]; 
 

 
const Header = ({players}) => 
 
    <ul>{players.map(({name,score}) => 
 
    <li><span>{name}</span><span>{score}</span></li>)}</ul> 
 

 
// App component 
 
class App extends React.Component { 
 

 
    // get rid of constructor if you're not doing anything with it 
 
    // constructor() { ... } 
 

 
    // use componentWillMount instead of componentDidMount 
 
    componentWillMount() { 
 
    this.setState({ 
 
     players: this.props.initialPlayers 
 
    }) 
 
    } 
 

 
    // don't wrap everything in a div if it's not necessary 
 
    render() {  
 
    return <Header players={this.state.players} /> 
 
    } 
 
} 
 

 
// Render component 
 
ReactDOM.render(<App initialPlayers={ PLAYERS }/>, 
 
document.getElementById('root'));
span { 
 
    display: inline-block; 
 
    font-weight: bold; 
 
    margin-right: 1em; 
 
} 
 

 
span ~ span { 
 
    font-weight: normal; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> 
 

 
<div id="root"></div>

0

の説明あなたがstateを初期化する必要がまずにそれを比較しますそれ以外の場合は値を更新する際にエラーが発生しますので、setState mを使用する必要がありますethodが設定プレイヤーは自分のコンストラクタ()に並ぶ

import React from 'react'; 
import ReactDOM from 'react-dom'; 

var PLAYERS = [ 
    { 
    name: 'xyz', 
    score: 123 
    } 
]; 

class App extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     players: [] 
    }; 
    } 
    componentDidMount() { 
    this.setState({ 
     players: this.props.initialPlayers 
    }); 
    } 
    render() { 
    return(
     <div> 
     <ul> 
      {this.renderPlayers()} 
     </ul> 
     </div> 
    ); 
    } 
    renderPlayers() { 
    return this.state.players.map((player, index) => 
     <li key={index}>{`name: ${player.name} - score: ${player.score}`}</li> 
    ); 
    } 
} 

ReactDOM.render(
    <App initialPlayers={ PLAYERS }/>, 
    document.getElementById('root') 
); 
+0

誤ってcomponentDidMountを使用した場合、ESlint自体はこれに対してエラーをスローします。代わりに、componentWillMountを使用する必要があります。 – Namish

+0

これは正しいです、この場合、最良の選択は** componentWillMount ** –

関連する問題