2016-08-23 3 views
1
import React from 'react'; 
import ReactDOM from 'react-dom'; 
import axios from 'axios'; 

var mode=['recent', 'alltime']; 

var Button = React.createClass({ 
    render(){ 
    return <input type={this.props.type} onClick= {this.props.onClick} text={this.props.val}/>; 
    } 
}); 

class Header extends React.Component { 
    constructor(){ 
    super() 
    } 

    render(){ 
    return <h2>Free Code Camp Leader board</h2> 
    } 
} 

class Leader extends React.Component{ 
    constructor(props){ 
    super(props) 
    this.state = { 
     users: [], 
     val: props.m, 
    } 
    } 

    componentDidMount() { 
    var th =this; 
    this.serverRequest = axios.get("https://fcctop100.herokuapp.com/api/fccusers/top/"+this.state.val).then(function(result){ 
     console.log(result.data); 
     var leaders = result.data; 
     this.setState({ 
     users: leaders 
     }); 
    }.bind(this)); 
    } 

    componentWillUnmount() { 
    this.serverRequest.abort(); 
    } 

    render(){ 
    return (
     <div className='container'> 

     <div className="tbl"> 
      <table className="table"> 
      <thead> 
       <tr> 
       <th>Name</th> 
       <th>Recent </th> 
       <th>Alltime</th> 
       </tr> 
      </thead> 
      <tbody> 
       {this.state.users.map(function(data, index){ 
       return (<tr key={index}><td><img src={data.img} className="img img-thumbnail" width="50"/>{data.username}</td> 
       <td id='recent'>{data.recent}</td> 
       <td id='alltime'>{data.alltime}</td></tr>) 
       })} 
      </tbody> 
      </table> 
     </div> 
     </div> 
    ) 
    } 
} 


class App extends React.Component{ 
    constructor(){ 
    super(), 
    this.state={val: mode[0]}, 
    this.update= this.update.bind(this), 
    this.unmount=this.unmount.bind(this) 
    } 

    unmount(){ 
    ReactDOM.unmountComponentAtNode(document.getElementById('board')) 
    } 

    update(){ 
    this.unmount(); 
    this.setState({val: this.state.val ===mode[0]? mode[1] : mode[0]}); 
    } 

    render(){ 
    return (
     <div> 
     <div className='header'> 
      <Header /> 
      <button onClick={this.update} >{this.state.val==mode[0]? mode[1] : mode[0]}</button> 
     </div> 
     <div id="board"> 
      {this.state.val === mode[0]? <Leader m= {this.state.val} /> : this.state.val === 
      mode[1] ? <Leader m= {this.state.val} /> : null} 
     </div> 
     </div> 
    ); 
    } 
} 

export default App; 

疑問のある部分は、App App React.Componentを継承しています。 Leader Componentを更新メソッドの状態変更で再レンダリングしようとしています。状態を変更しますが、リーダーに渡されたプロパティを変更して再レンダリングしません。ReactJSなぜこの状態変化はレンダリングされませんか?私は間違って何をしていますか?

+1

'unmount()'を呼び出す目的は何ですか?その行をコメントするだけで同じ動作をしますか? – azium

+0

私は問題は 'componentDidMount'が最初のレンダリングの直後に(サーバ上ではなく)クライアント上で一度しか呼び出されないと思います。 'this.state.val'をリーダーレンダリングに移動すると更新されます。 –

+0

okありがとう、ええ、unmount()関数はvalプロパティのsteStateの前にリーダーをアンマウントしようとする実験に過ぎません現在のところ、削除する必要のある無駄な機能です。 –

答えて

1

Leaderの中には、mの初期レンダリング後に何もしていません。したがって、レンダリングは再実行されますが、状態は変更されません。 constructorは、最初にrenderの前に1回だけ呼び出されることに注意してください。したがって、Leaderが最初のrenderの後にプロップ変更に応答し、それに応じて状態を更新するようにするには、component lifecycle methodsのいずれかを使用する必要があります。

LeaderコンポーネントにcomponentWillReceiveProps lifecycle methodを追加することをおすすめします。これはそれを行う必要があります。

componentWillReceiveProps(nextProps) { 
    this.setState({ val: nextProps.m }); 
} 

をお使いのコンポーネントの内部で何が起こっているかをテストするための簡単な方法は、単に、コンポーネントのrenderの最初の行としてを追加することです。

+0

ok、thankyou私はコンピュータに戻って、それがどのように動作するかを知らせるときに、その方法を試みます。私はそれが実際にトリックをするかもしれないと思う。 –

+0

私はこの解決策は良いと思いますが、質問する価値はありますが、App状態をリーダーに複製する必要がありますか?リーダーの中で 'props.m'を使うのはなぜですか? – azium

+0

合意。私は、現在の実装で間違っていることをOPに見せようとしています。 –

関連する問題