2017-03-29 2 views
0
class Main extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     generations: 0, 
     rows: 30, 
     cols: 30, 
     isGoing: false, 
     speed: 500, 
     gameField: [] 
    } 

    this.generateGameField() 
    } 

    generateGameField() { 
    var result = []; 
    for (let i = 0; i < this.state.rows; i++) { 
     result[i] = []; 
     for (let j = 0; j < this.state.cols; j++) { 
     result[i][j] = Math.round(Math.random()); 
     } 
    } 
    console.log(result) 
    this.setState({ gameField: result }) 

    } 

    render() { 
    return (
     <button onClick={() => console.log(this.state)}>Click me</button> 
    ) 
    } 

} 


ReactDOM.render(
    <Main />, 
    document.body 
) 

도와주세요. 함수 generateGameField 새 배열을 만들고 0 또는 1 채 웁니다. 실제로 배열을 만들지 만 상태를 변경하지 않습니다. 함수 내에서 상태에 액세스 할 수 있으므로 무엇이 잘못되었는지 알 수 없습니다.React ES6 클래스의 기능이 상태를 변경하지 않습니다

+0

당신이 생성자에서 상태를 설정하는 거라면, 왜 그냥 같은 초기 상태에 넣어? 'generateGameField'와'this.state = {...} '에서'result'를 반환합니다.'gameField : this.generateGameField()'. – Li357

+0

고맙습니다. 나는 이것을 알고 있었지만, 왜 내 코드가 어떻게되는지를 알고 싶다. 내 기능이 주에 대한 액세스 권한을 가지지 만 변경할 수없는 이유는 무엇입니까? –

+0

예, setState는 비동기입니다. 그러나 버튼을 클릭 한 후 내 상태를 인쇄해야하는 버튼을 추가했습니다. 그리고 국가는 전혀 변하지 않을 것입니다. 5, 10, 15 초 후에 버튼을 클릭 할 수 있으며 상태는 그대로 유지됩니다. –

답변

0

구성 요소를 초기화하려고하는 것 같습니다. 그것이 당신이 달성하고자하는 것이라면 반응 라이프 사이클 방법을 사용해야합니다. componentWillMount. 호출)

componentWillMount (:

그래서, 버그를 수정 componentWillMountgenerateGameField 기능을 이름을 변경하고 다음과 같이 코드를 재구성 : 나는에있는 어떤이 공식 문서를 반응

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

    componentWillMount() { 
     let result = []; 
     const rows = 30; 
     const cols = 30; 
     for (let i = 0; i < rows; i++) { 
      result[i] = []; 
      for (let j = 0; j < cols; j++) { 
       result[i][j] = Math.round(Math.random()); 
      } 
     } 
     console.log(result) 
     this.setState({ 
     generations: 0, 
     rows: 30, 
     cols: 30, 
     isGoing: false, 
     speed: 500, 
     gameField: result 
     }) 

    } 

    render() { 
     return (
     <button onClick={() => console.log(this.state)}>Click me</button> 
     ) 
    } 

} 

ReactDOM.render(<Main />,document.body) 

을 장착이 이루어지기 직전. render() 전에 호출되기 때문에이 메서드에서 상태를 설정하면 다시 렌더링되지 않습니다. 이 방법에서는 부작용이나 구독을 피하십시오.

이것은 서버 렌더링시 호출되는 유일한 라이프 사이클 후크입니다. 일반적으로 대신 생성자()를 사용하는 것이 좋습니다.

위의 코드가 준수가에 수정할 수 :

class Main extends React.Component { 
    constructor(props) { 
     super(props); 
     let result = []; 
     const rows = 30; 
     const cols = 30; 
     for (let i = 0; i < rows; i++) { 
      result[i] = []; 
      for (let j = 0; j < cols; j++) { 
       result[i][j] = Math.round(Math.random()); 
      } 
     } 
     console.log(result); 
     this.state = { 
     generations: 0, 
     rows: 30, 
     cols: 30, 
     isGoing: false, 
     speed: 500, 
     gameField: result 
     }; 
    } 

    render() { 
     return (
     <button onClick={() => console.log(this.state)}>Click me</button> 
     ) 
    } 

} 

ReactDOM.render(<Main />,document.body) 
+0

감사합니다. 그것은 작동합니다. 하지만 나는 constructor 함수 내부에서 상태를 초기화해야한다고 생각했다. –

+0

당신이 맞다. 그것은 반응 공식 문서에서 추천 한 것이다. 방금 다른 옵션을 추가했습니다. – cdaiga

관련 문제