2017-04-25 94 views
3

我有這個簡單的組件,initialPlayers道具傳遞給App組件。如何從傳遞給組件的反應道具中設置狀態?

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')); 

有此錯誤控制檯,並不能值傳遞給Header組件作爲{this.state.players}。任何想法?。

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

移動設置的玩家排隊到你的構造函數():

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

這是Facebook如何做到這一點,如他們的文檔所示:https://reactjs.org/docs/react-component.html#constructor – Rohmer

1

你想用componentWillMount,因爲它運行前組件的第一渲染 - 比較,爲的componentDidMount

你需要初始化state說明

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

第一否則你會得到錯誤更新它的價值,那麼你必須使用setState米ethod改變它(這是更新的反應state推薦的方式)

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 ** –

相關問題