React.js,从同级更新所有子组件

时间:2019-04-28 07:41:08

标签: javascript reactjs ecmascript-6 components

我在reactjs上进行了排序,我不明白如何重画所有子组件,以便只有选中的一个组件保持活动状态,我可以更新当前的子组件,而其他组件则不会更改。这是示例代码。谁能帮助/解释正确的做法?

nodejs,webpack,最后的reactjs

App.js

import React, { Component } from "react";
import Parent from "./Parent";

class App extends Component {
    render() {
        return(
            <Parent />
        )
    }
}

export default App;

Parent.js

import React, { Component } from "react";
import Child from "./Child";

class Parent extends Component {

    constructor(props) {
        super(props);
        this.state = {
            popularity: {"sorting": "desc", "active": true},
            rating: {"sorting": "desc", "active": false},
            reviews_count: {"sorting": "desc", "active": false},
        };
    }

    updateFilters = () => {
        // ??
    };

    render() {
        return (
            <div>
                <Child type="popularity" sorting={this.state.popularity.sorting} active={this.state.popularity.active} updateFilters={this.updateFilters} />
                <Child type="rating" sorting={this.state.rating.sorting} active={this.state.rating.active} updateFilters={this.updateFilters} />
                <Child type="reviews_count" sorting={this.state.reviews_count.sorting} active={this.state.reviews_count.active} updateFilters={this.updateFilters} />
            </div>
        )
    }
}

export default Parent;

Child.js

import React, { Component } from "react";

class Child extends Component {

    handleClick = () => {
        this.props.updateFilters();
    };

    render() {
        let activeStr = "";

        if (this.props.active) {
            activeStr = "active"
        } else {
            activeStr = "inactive";
        }

        return(
            <div onClick={() => this.handleClick}>
                {this.props.type} {activeStr} {this.props.sorting}
            </div>
        );
    }
}

export default Child;

1 个答案:

答案 0 :(得分:1)

假设您尝试将单击类型的活动标志设置为true,并将所有其他类型设置为false。


<div onClick={() => this.handleClick}>,这是不正确的,因为您没有调用该函数。可以更正为:

<div onClick={() => this.handleClick()}>

然后您可以更新handleClick以传递类型:

handleClick = () => {
  this.props.updateFilters(this.props.type);
};

OR

您可以忽略该handleClick并调用prop函数:

<div onClick={() => this.props.updateFilters(this.props.type)}>

将类型传递回updateFilters后,我们可以简单地遍历先前的状态属性,将所有类型的活动标志设置为false。但是,如果键与单击的类型匹配,则将其设置为true。

  updateFilters = type => {
    this.setState(prevState => {
      return Object.keys(prevState).reduce(
        (result, key) => ({
          ...result,
          [key]: { ...prevState[key], active: key === type }
        }),
        {}
      );
    });
  };

您的Child组件可以大量重构为Pure Functional组件,从而使其更加简单:

const Child = ({ type, active, updateFilters, sorting }) => (
  <div onClick={() => updateFilters(type)}>
    {type} {active ? "active" : "inactive"} {sorting}
  </div>
);

工作解决方案: https://codesandbox.io/s/4j83nry569