简体   繁体   English

将 state 从子组件提升到父组件

[英]Lifting state from child component to parent

I have 2 child components: a Categories select and a Search input text and submit button.我有 2 个子组件:一个Categories select 和一个Search输入文本并提交按钮。 They both have their own state. I have to use those two components in a parent page.他们都有自己的 state。我必须在父页面中使用这两个组件。 I need to know in which category I have to do the search and to achieve this I think I should lift the state, so that the parent will handle it.我需要知道我必须在哪个类别中进行搜索,为了实现这一点,我认为我应该解除 state,以便家长处理它。

Basically I removed state from the child component and placed it on the parent, ending up with something like this (simplified code):基本上我从子组件中删除了 state 并将其放在父组件上,最后得到这样的东西(简化代码):

export default ParentPage = () => {

  const [searchString, setSearchString] = useState("");
  const [category, setCategory] = useState(0);

  const onSearch = () => {
    // search for searchString in the selected category
  }

  return (
    <>
      <Categories category={category} setCategory={setCategory} />
      <Search searchString={searchString} setSearchString={setSearchString} onSearch={onSearch} />
    </>
  )
}

Is this a good approach?这是一个好方法吗? It seems a bit verbose, is there a more compact way to pass the state and setState to child components?看起来有点冗长,有没有更紧凑的方式将 state 和 setState 传递给子组件?

In place of this:代替这个:

<Categories category={category} setCategory={setCategory} />
<Search searchString={searchString} setSearchString={setSearchString} />

You can also use the below one, as you are keeping same name props as states:你也可以使用下面的,因为你保留了与状态相同的名称道具:

<Categories {...{ category , setCategory }} />
<Search {...{ searchString , setSearchString }} />

Note: But I can't see any purpose of lifting state up, from the provided code, so can't say anything about it.注意:但是我从提供的代码中看不到提升 state 的任何目的,所以不能说什么。


After the code update, you can do it something like this:代码更新后,您可以这样做:

export default ParentPage = () => {

  const [searchString, setSearchString] = useState("");
  const [category, setCategory] = useState(0);

  const onSearch = () => {
    // search for searchString in the selected category

    // if you are filtering category and calling setCategory, then it's all good
    // else you need to pass `searchString` in `Categories` to filter the data

  }

  return (
    <>
      <Categories {...{category , setCategory }} />
      <Search {...{searchString , setSearchString , onSearch}} />
    </>
  )
}

Hi I have prepared a complete example here.您好,我在这里准备了一个完整的示例。 You need to pass child state from child to parent using callback and then you receive child's state on parent and send that state to another child.您需要使用回调将子项 state 从子项传递给父项,然后您在父项上收到子项的 state 并将该 state 发送给另一个子项。

Parent Component父组件

import React, {useEffect, useState} from 'react';
import Child from "./Child";
import Sibling from "../Sibling";

function CParent(props) {

    const [status, setStatus] = useState(false);

    function setOpeningValue(status) {
        console.log('From Child to Parent:' + status);
        setStatus(status);
    }
    return (
        <div>
            <Child setOpeningValue={setOpeningValue}/>
            <Sibling status={status}/>
        </div>
    );
}
export default CParent;

Child Component子组件

import React, {useEffect, useState} from 'react';

// Child to Parent communication
function Child(props) {
    const {setOpeningValue} = props;
    const [isOpen, setOpen] = useState(false);

    function clickHandler() {
        setOpen(!isOpen);
        setOpeningValue(`changes is ${!isOpen}`);
    }
    return (
        <div>
            <button onClick={clickHandler}>Open</button>
        </div>
    );
}
export default Child;

Sibling Component兄弟组件

import React, {useEffect, useState} from 'react';

function Sibling(props) {
    const {status} = props;
    const [isOpen, setOpen] = useState(false);

    return (
        <div>
            From Child to Parent to Another Child (Sibling) {status}
        </div>
    );
}
export default Sibling;

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

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