为什么看不到子组件事件处理程序的父状态?

时间:2020-09-29 02:38:01

标签: reactjs

我有两个组成部分:进餐成分成分始终是膳食的子代。我将以下功能作为道具传递给每个成分,例如<Ingredient deleteIngFunc={handleDeleteIng} />

单击“成分”中的按钮后,成分会触发prop.deleteIngFunc,但是当我从函数中调试ingsArrayCopy时,它是空的!它不应该为空,因为页面渲染时显然处于该状态(即,成分显示在页面上,因此状态显然不为空)

Meal.js

import React, {useState, useEffect} from 'react';
import Ingredient from './Ingredient';

function Meal(props){
    const [ingArray, setIngArray] = useState([]);

    function handleDeleteIng(e){
        let ingsArrayCopy = [...ingArray];
        console.debug(ingsArrayCopy); // empty array??
    }

    async function initIngs(){
        let ings = props.ings.map(
            ing => (
                <Ingredient title={ing.title} id={ing.id} deleteIngFunc={handleDeleteIng} />
            )
        )

        return await setIngArray(prev => ings)
    }

    function updateIngs(newIngObject){
        let oldIngState = [...ingArray];

        let newIng = <Ingredient key={newIngObject.id} id={newIngObject.id} title={newIngObject.title} />

        let newIngState = oldIngState.concat([newIng]);

        setIngArray(prev => newIngState);
    }


    useEffect(
        () => {
            initIngs();
        },
        []
    );

    return (
        <ul>
            {ingArray}
        </ul>
    );
}

export default Meal;

Ingredient.js

import React, {useState, useEffect} from 'react';
import CancelIcon from '@material-ui/icons/Cancel';
import Typography from '@material-ui/core/Typography';
import IconButton from '@material-ui/core/IconButton';

function Ingredient(props){

    function handleDeletion(e){
        e.preventDefault()
        props.deleteIngFunc(e)
    }

    return (
        <li
            key={props.id}
            className="ingredient-listitem"
        >
            <Typography className="ingredient-text">{props.title}</Typography>

            <IconButton onClick={handleDeletion}>
                <CancelIcon></CancelIcon>
            </IconButton>
        </li>
    )
}

export default Ingredient;

1 个答案:

答案 0 :(得分:1)

否,状态值不能在常规函数内部访问。只能通过以下反应挂钩useEffect() useCallback() useMemo()和功能组件的return语句进行访问。

例如:

function App() {
  const [state, setState] = useState('initial Value')

  function someFunction(){
    // It's not recommended to access the state inside of this function
    // cause the value of the state will always be ('initial Value')
    // even if the state were updated
    console.log(state)
   // Why ?
   // Because regular function like this cannot have dependency array
   // And thus without dependency array function will not know that state has changed
  }

  useEffect(()=>{
    // It's good if you access the value of the state here
    // It will be assured it will always have the updated value
    console.log(state)
  },[state]) 


  return (
    // You can also access the value of the state inside return statement        
    <>
    {console.log(state)}
    <SomeComponent props={state}/>
    </>
  )
}

此外:您可以在常规功能上设置状态,但不能访问或读取常规功能上的状态

我包括了一个codeandbox链接,用于进行针对您的问题的演示

https://codesandbox.io/s/accessingstate-03hud?file=/src/App.js