【问题标题】:Change parent's state using funciton in child component使用子组件中的函数更改父状态
【发布时间】:2017-01-11 14:07:50
【问题描述】:

如何使用 setState [child to parent] 重新渲染数据? FoodList 中的 deleteItem 函数应删除所选数据并重新渲染。我不是要求删除代码,而是我将如何重新渲染在子组件中具有函数的主组件,该子组件应该 deleteItem 进行重新渲染

我有 3 个组件。 Main、Food 和 FoodList。

主组件 - 通过状态保存数组中的食物列表并将其作为道具传递给食物组件。

class Main extends Component{
    constructor(){
        super();
        this.state = {
            foods: []
        };
    }
    
    componentWillMount(){
        this.setState({
            foods: [
                {
                    id: uui.v4(),
                    name: "Chocolate Cake",
                    category: "dessert"
                },
                {
                    id: uui.v4(),
                    name: "Milkshake",
                    category: "beverage"
                }
            ]
        });
    }
    
    render(){
        return(<Food lists={this.state.foods}/>);
    }
}

食物组件 - 映射接收到的食物列表道具并将其传递给 FoodList 组件以呈现为 lis

class Food extends Component{
    render(){
        let items;
        //check if object has value;
        if(this.props.lists)
        {
            items = this.props.lists.map(food => {
                //pass each food as props
                return <FoodList key={food.id} food_list={food} />;
            });
        }
        
        return(
            <div>
            <h3>Available Foods</h3>
            {items}
            </div>
        );	
    }
}

FoodList 组件 - 接收映射的道具并渲染为 li

class FoodList extends Component {
    
    deleteItem(id)
    {
        console.log(id);
        //delete item using passed id and re rende food state in Main Component
    }
    
    render(){
        return <li>{this.props.food_list.name} - {this.props.food_list.category}
        <a href="#" onClick={this.deleteItem.bind(this, this.props.food_list.id)}>Delete</a>
        </li>
    }
}

【问题讨论】:

  • 旁注,您可以在构造函数中设置状态并摆脱 componentWillMount
  • 先生,我正在关注 youtube 上的教程,他更喜欢 componentWillMount() 吗?你认为先生是最好的选择?
  • 如果您已经拥有数据(您拥有),那么我会将其分配给构造函数中的状态。您已经在分配食物:[],然后在 componentWillMount 中再次分配。您可以在构造函数中完成所有操作

标签: javascript reactjs


【解决方案1】:

我认为您可以在父组件上创建一个方法并将其作为道具传递给子组件

例子

class Main extends Component{
    constructor(){
        super();
        this.state = {
          foods: []
        };
    }

    deleteFood = (id) => {
      let foods = this.state.foods;
      let index = -1;
      for(let i = 0; i < foods.length; i++){
        if(foods[i].id == id){
          index = i;
          break;
        }
      }
      if(index == -1){
        return;
      }
      foods.splice(index, 1);
      this.setState({foods: foods});
    }

    componentWillMount(){
        this.setState({
            foods: [
            {
                id: uui.v4(),
                name: "Chocolate Cake",
                category: "dessert"
            },
            {
                id: uui.v4(),
                name: "Milkshake",
                category: "beverage"
            }
            ]
        });
    }

    render(){
        return(<Food deleteFood={this.deleteFood} lists={this.state.foods}/>);
    }
}

对在你的 Food 组件中渲染 FoodList 做同样的事情

<FoodList key={food.id} food_list={food} deleteFood={this.props.deleteFood} />

最后在你的 foodlist 组件中使用它

deleteItem(id)
    {
        console.log(id);
        this.props.deleteFood(id);
        //delete item using passed id and re rende food state in Main Component
    }

【讨论】:

  • 别忘了将'this'绑定到deletFood
  • 嗨@TMitchell 我认为你在使用箭头函数时不需要使用绑定
  • 正确,但 React 类实例的属性不会自动绑定。它们是在使用 React.createClass 时,但在扩展 React.Component 时它们不是 - toddmotto.com/react-create-class-versus-component/…
  • @TMitchell 是的,这适用于像hello(){} 这样的属性,但是hello = ()=&gt;{} 将保留“this”..这就是我在代码中使用的:)
【解决方案2】:

将此添加到您的主要组件

deleteItem(id) {
  this.setState({
    foods: this.state.data.filter(food => food.id !== id)
  })
}

通过你的组件传递它

<Food lists={this.state.foods} deleteItem={this.deleteItem.bind(this)}/>

-

items = this.props.lists.map((food, index) => {
  return <FoodList key={food.id} food_list={food} deleteItem={this.props.deleteItem}/>;
});

点击删除按钮调用它

deleteItem(id) {
  this.props.deleteItem(id);
}

<a href="#" onClick={this.deleteItem.bind(this, id)}>Delete</a>

【讨论】:

  • SIr 我真的是 React 新手。我应该总是为 Main 创建一个函数并将其作为 props 传递吗?
  • 这是一种做事方式。另一个是研究 Flux 以获得更高级/更大规模的应用程序(谷歌 Flux 和 redux)。在这种情况下,如果你想编辑父组件的状态,修改函数需要来自同一个组件
猜你喜欢
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 1970-01-01
  • 1970-01-01
  • 2021-02-13
  • 2018-11-03
相关资源
最近更新 更多