反应onClickTowget

时间:2017-08-02 18:56:24

标签: reactjs onclick styles

我正在尝试构建一个简单的动态更新的交互式列表,根据.clicked类的css规则对每个<li></li>进行样式设置,当您单击它们时。

该应用程序由两个组件组成,父项和子项,所讨论的代码如下(取自孩子):

handleClick(e) {


    document.getElementById(e.currentTarget.id).setAttribute("class","clicked");


}  

render() {

let ar = this.props.sentences;


let pro = ar.map((x,i)=>{ return (<li id={i} key={i} className={i%2==0 ? "white" : "grey"} 
onClick={this.handleClick}>{x}</li>); })

return (
    <div>

        <ul id="ul">{ pro }</ul>                

    </div>

这里发生的事情基本上是父母将一个句子传递给孩子(一系列句子将形成动态列表的基础)。

有争议的部分是我以document.getElementById(e.currentTarget.id).setAttribute("class","two"); 的形式使用DOM操作,以便从jsx更改动态创建的html的类。

上面的代码,但它不是最佳做法。使用react的全部优势是使用虚拟dom并优化DOM的更新方式。

我的问题如下:

1)我是否有这种感觉? (我的解决方案不是最佳做法?)

2)(如果是这样,)我如何构建我的代码以便使用虚拟dom机器做出反应?

如果您知道此问题是重复的,请发表评论,我会将其删除。

1 个答案:

答案 0 :(得分:2)

  

1)我是否有这种感觉? (我的解决方案不是最佳做法?)

假设这不是一种理想的方法是正确的,在React中通过vanilla js操纵DOM有它的位置(Example Use Cases)但除非绝对必要,否则不应该这样做。此外,使用Array.prototype.map中的索引作为组件上的键是不理想的,就像它们改变顺序一样,它可能会导致React混淆,因为在这种情况下键会以不同的方式映射。

  

2)(如果是这样,)我如何构建我的代码以便使用虚拟dom机器反应提供?

您应该使用组件状态。如果您希望每个单击的元素都维护clicked类,那么创建一个状态来缓存已经收到clicked类的元素。如果只有最近点击的元素获得clicked类,则只需将标识符缓存到状态中的相应元素。你也可以使用refs来达到这个目的,虽然facebook有些不鼓励他们的过度使用。

这是一个快速剪切,可以切换每个click

上的<li>课程
class Test extends Component {
    constructor() {
        super();

        this.state = {
            clicked: {}
        };
    }

    render() {
        let ar = this.props.sentences;

        let pro = ar.map((x, i) => {
            const color_class = i % 2 === 0 ? "white" : "grey";
            const clicked_class = this.state.clicked[i] === true ? "clicked" : "";

            let clicked = Object.assign({}, this.state.clicked); // Dont mutate state!!!

            return (
                <li
                    id={i}
                    key={i}
                    className={`${color_class} ${clicked_class}`}
                    onClick={e => {
                        if (clicked.hasOwnProperty(i)) {
                            delete clicked[i];
                        } else {
                            clicked[i] = true;
                        }
                        this.setState({ clicked });
                    }}
                >
                    {x}
                </li>
            );
        });

        return (
            <div>
                <ul id="ul">
                    {pro}
                </ul>
            </div>
        );
    }
}