没有在this.setState()上调用render()

时间:2016-08-16 08:30:52

标签: javascript reactjs

我有一个简单的导航链接组件,在Container / Presentational类(Smart / dumb)中分开,如下所示:

我的演讲内容:

import React, { PropTypes } from 'react';

class Navigation extends React.Component {

    componentWillReceiveProps() {
        console.log("here bro componentWillReceiveProps");
    }

    render() {
        console.log(this.props);
        var self = this;
        return (
            <div>
                <ul>
                    {
                        this.props.items.map( (m, index) => {
                            var style = '';

                            console.log("index", index, "focus", self.props.focused);
                            if(self.props.focused == index){
                                style = 'focused';
                            }
                            return <li key={Math.random()} className={style} onClick={self.props.clickHandler.bind(this, index)}>{m}</li>;
                        })
                    }
                </ul>

                <p>Selected: {this.props.items[this.props.focused]}</p>
            </div>
        );
    }
}

export default Navigation;

我的容器组件:

import React, {PropTypes} from 'react';
import Nav from '../components/Navigation';

class NavigationContainer extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            focused : 0
        };
    }

    clicked(index) {
        this.setState({focused: index}, function () {
            console.log("set to", this.state.focused);
        });
    }

    render() {
        return (
            <Nav items={['Home', 'About', 'Contact Us']} clickHandler={this.clicked} focused={this.state.focused}/>
        );
    }
}

NavigationContainer.propTypes = {};
export default NavigationContainer;

当点击任何项目(主页,联系我们等)并修改状态时,不会再次调用render()方法,因此传递哑组件的道具是最新的。我的理解是当状态发生变异时,会调用render()。我在这做错了什么?

1 个答案:

答案 0 :(得分:4)

使用ES2015类语法extend React.Component时,您需要将操作处理程序绑定到类的上下文。

试试这个:

render() {
        return (
            <Nav items={['Home', 'About', 'Contact Us']} clickHandler={index => this.clicked(index)} focused={this.state.focused}/>
        );
    }

通常,最好不要在bind内使用箭头函数或render方法,因为它会在任何render调用上生成函数的新副本。将函数声明移动到class constructor

我个人更喜欢在这种情况下使用箭头函数作为类属性

class MyClass extends React.Component {

  handleClick = () => {
    // your logic
  };

  render() {
    return (
      <button onClick={this.handleClick}>Click me</button>
    );
  }
}

它不是ES2015规范的一部分,但babel stage-0 preset支持此语法

您可以在this article

中的React中阅读有关上下文绑定的更多信息