简体   繁体   English

如何从 function 内部访问我的反应钩子 state

[英]How can I access my react hooks state from inside a function

I have an app that shows some questions when the user presses a button.我有一个应用程序,当用户按下按钮时会显示一些问题。 On each questions I have a condition to determine if the "Back" button should be shown on the question - appState.questions.length > 0 .在每个问题上,我都有一个条件来确定是否应在问题上显示“返回”按钮 - appState.questions.length > 0

My problem is that the state is not being reached from the function where I am calling it.我的问题是 state 没有从我调用它的 function 到达。

let questionComponent = (currentCardKey, textAreaText = "") => {
    console.log(`Question length inside: ${appState.questions.length}`)
    return <Question
        textAreaText={"ereer"}
        // I can not access appState from here.
        shouldShowBackButton={appState.questions.length > 0}
        measureTextChangeHandler={measureTextChangeHandler}
        onChosenDataTypeChanged={onChosenDataTypeChanged}
        aimTextChangeHandler={aimTextChangeHandler}
        onButtonClicked={onButtonClicked}
        currentCardKey={currentCardKey}/>
}

The structure of my code.我的代码结构。

function App(){
    const [appState, setAppState] = useState(
        {
            questions: [], //[<Question />, <Question />]
            independentVariablesCount: 0,
        }
    )
    const [currentCard, setCurrentCard] = useState();
    
    const addToQuestion = (questionObject) => {
        setAppState(prevState => {
            questionLength.current = appState.questions.length
            return {...prevState, questions: [...prevState.questions, questionObject]}
        })
    }

    // I can access appState outside the function
    
    let questionComponent = (currentCardKey, textAreaText = "") => {

        console.log(`Question length inside: ${appState.questions.length}`)

        return <Question
            textAreaText={"ereer"}
           // I can not access appState inside this function
            shouldShowBackButton={appState.questions.length > 0}
            measureTextChangeHandler={measureTextChangeHandler}
            onChosenDataTypeChanged={onChosenDataTypeChanged}
            aimTextChangeHandler={aimTextChangeHandler}
            onButtonClicked={onButtonClicked}
            currentCardKey={currentCardKey}/>
    }

    const onButtonClicked = (_buttonText, previousCardComponent) => {
        const previousCard = previousCardComponent
        const previousCardMainText = previousCardComponent.props.mainText
        ...
        switch (_buttonText) {
            case buttonText["NEXT"]:
                switch (previousCardMainText){
                    case questionData["CAT_QUESTION"]:
                        addToQuestion(previousCard)
                        setCurrentCard(questionComponent("CAT_FOOD_QUESTION"))
                        break
                }
            ...
                break
        }
    }

    return (
        <div>{currentCard}</div>
    )
}

I have tried updating the function inside useEffect() but that does not solve the problem.我尝试在useEffect()中更新 function 但这并不能解决问题。 I have searched for solutions such as useState function is not working in functional component and React hooks setState not updating immediately but none of these work.我已经搜索了诸如useState function 之类的解决方案在功能组件中不起作用,并且React 挂钩 setState 没有立即更新,但这些都不起作用。

How can this issue be resolved?如何解决这个问题?

Two things I did wrong, I did not remember to add the first question to the state array when the start button is clicked and I did not make a way for the question component to be re-rendered with the correct value when the question length changes.我做错了两件事,我不记得在单击开始按钮时将第一个问题添加到 state 数组中,并且当问题长度更改时,我没有为问题组件重新呈现正确的值做准备. Used the useRef hook to store the questionComponent function.使用useRef挂钩存储questionComponent function。

So I used the useRef hook to store the questionComponent and used the addToQuestion function I had.所以我使用useRef挂钩来存储questionComponent并使用我拥有的addToQuestion function。

const questionComponent = useRef()

useEffect(()=>{
    questionComponent.current = (currentCardKey, textAreaText = "") => {
        console.log(`Question length inside: ${appState.questions.length}`)
        return <Question
            textAreaText={"ereer"}
            shouldShowBackButton={appState.questions.length > 0}
            measureTextChangeHandler={measureTextChangeHandler}
            onChosenDataTypeChanged={onChosenDataTypeChanged}
            aimTextChangeHandler={aimTextChangeHandler}
            onButtonClicked={onButtonClicked}
            currentCardKey={currentCardKey}/>
    }
})

const onStartButtonClick = () => {
    setStartButtonIsClicked(true)
    setCurrentCard(questionComponent.current("CAT_FOOD_QUESTION"))
    addToQuestion(questionComponent.current("CAT_FOOD_QUESTION"))
}

you access to the initial appState due to the javascript clousure feature, so the appState length keeps 0 all the time.由于 javascript clousure 功能,您可以访问初始 appState,因此 appState 长度始终保持为 0。

try this:尝试这个:

let questionComponent = React.useMemo((...) => {}, [appState]);

then you can access to the newest appState然后就可以访问最新的appState

Have you tried to use useCallback?您是否尝试过使用 useCallback?

Const questionComponent = useCallback((currentCardKey, textAreaText = "") => {

        console.log(`Question length inside: ${appState.questions.length}`)

        return <Question
            textAreaText={"ereer"}
           // I can not access appState inside this function
            shouldShowBackButton={appState.questions.length > 0}
            measureTextChangeHandler={measureTextChangeHandler}
            onChosenDataTypeChanged={onChosenDataTypeChanged}
            aimTextChangeHandler={aimTextChangeHandler}
            onButtonClicked={onButtonClicked}
            currentCardKey={currentCardKey}/>
    },[appState])

Hope it helps!希望能帮助到你!

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

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