简体   繁体   English

如何从子组件触发父组件重新渲染

[英]How to trigger re-render in Parent Component from Child Component

, Using props I was able to effectively pass state upwards from my child component to its parent, but a change in the state does not cause a re-render of the page. ,使用道具我能够有效地将 state 从我的子组件向上传递到它的父组件,但是 state 的变化不会导致页面的重新渲染。

import React, { useState } from "react";

export default function App() {
  const AddToList = (item) => {
    setText([...text, item]);
  };
 const removeFromList = (item) => {
    const index = text.indexOf(item);
    setText(text.splice(index, 1));
  };
  const [text, setText] = React.useState(["default", "default1", "default2"]);
  return (
    <div className="App">
      <div>
        <button
          onClick={() => {
            AddToList("hello");
          }}
        >
          Add
        </button>
      </div>
      {text.map((item) => {
        return <ChildComponent text={item} removeText={removeFromList} />;
      })}
    </div>
  );
}

const ChildComponent = ({ text, removeText }) => {
  return (
    <div>
      <p>{text}</p>
      <button
        onClick={() => {
          removeText(text);
        }}
      >
        Remove
      </button>
    </div>
  );
};

In the snippet, each time AddToList is called, a new child component is created and the page is re-rendered reflecting that.在代码片段中,每次调用 AddToList 时,都会创建一个新的子组件,并重新呈现页面以反映这一点。 However, when i call removeFromList on the child component, nothing happens.但是,当我在子组件上调用 removeFromList 时,没有任何反应。 The page stays the same, even though I thought this would reduce the number of childComponents present on the page.页面保持不变,尽管我认为这会减少页面上存在的 childComponents 的数量。 This is the problem I'm facing.这是我面临的问题。

Updated Answer (Following Edits To Original Question)更新的答案(在对原始问题进行编辑之后)

In light of your edits, the problem is that you are mutating and passing the original array in state back into itself-- React sees that it is receiving a reference to the same object, and does not update.根据您的编辑,问题是您正在改变 state 中的原始数组并将其传递回自身——React 看到它正在接收对相同 object 的引用,并且不会更新。 Instead, spread text into a new duplicate array, splice the duplicate array, and pass that into setText :相反,将text散布到一个新的重复数组中,拼接重复数组,然后将传递到setText中:

const removeFromList = (item) => {
    const index = text.indexOf(item);
    const dupeArray = [...text];
    dupeArray.splice(index, 1);
    setText(dupeArray);
};

You can see this working in this fiddle你可以在这个小提琴中看到这个工作

Original Answer原始答案

The reason React has things like state hooks is that you leverage them in order to plug into and trigger the React lifecycle. React 拥有 state 钩子之类的东西的原因是您可以利用它们来插入并触发 React 生命周期。 Your problem does not actually have anything to do with a child attempting to update state at a parent.您的问题实际上与尝试在父母处更新 state 的孩子没有任何关系。 It is that while your AddToList function is properly leveraging React state management:这是当您的AddToList function 正确利用 React state 管理时:

const AddToList = (item) => {
  setText([...text, item]);
};

Your removeFromList function does not use any state hooks:您的removeFromList function使用任何 state 挂钩:

const removeFromList = (item) => {
  const index = text.indexOf(item);
  text.splice(index, 1); // you never actually setText...
};

...so React has no idea that state has updated. ...所以 React 不知道 state 已经更新。 You should rewrite it as something like:您应该将其重写为:

const removeFromList = (item) => {
  const index = text.indexOf(item);
  const newList = text.splice(index, 1);
  setText(newList);
};

(Also, for what it is worth, you are being a little loose with styles-- your AddToList is all caps using PascalCase while removeFromCase is using camelCase. Typically in JS we reserve PascalCase for class es, and in React we also might leverage it for components and services; we generally would not use it for a method or a variable.) (此外,就其价值而言,您对样式有点松散——您的AddToList全部使用 PascalCase 大写,而removeFromCase使用驼峰式命名法。通常在 JS 中,我们为class es 保留 PascalCase,而在 React 中,我们也可能利用它用于组件和服务;我们通常不会将它用于方法或变量。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM