从子组件到父组件的提升状态

I have 2 child components: a Categories select and a Search input text and submit button. They both have their own state. I have to use those two components in a parent page. 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.

基本上,我从子组件中删除了状态,并将其放置在父组件上,最终得到了这样的代码(简化的代码):

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} />
    </>
  )
}

这是一个好方法吗?似乎有些冗长,是否有更紧凑的方法将state和setState传递给子组件?

评论
  • 换位思考
    换位思考 回复

    代替此:

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

    您还可以使用以下名称,因为您要保留与州相同的名称道具:

    <Categories { category , setCategory } />
    <Search { searchString , setSearchString } />
    
    注意:但是,从提供的内容中我看不到提升状态的任何目的   代码,所以就什么也不能说了。

  • Ula
    Ula 回复

    嗨,我在这里准备了一个完整的例子。您需要使用回调将子状态从子状态传递到父状态,然后在父状态上接收子状态,然后将该状态发送给另一个子状态。

    父组件

    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;
    

    子组件

    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;
    

    同级组件

    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;