我在我的React js项目中遇到了一个问题,这与传递一个handleClick函数(带有回调和一些id-prop)有关,因为我试图在顶层组件中管理我的状态。我想要实现的是,当我点击答案时,id被传递到顶层,这样我就可以正确地设置状态。
我的数据结构是这样的:一个包含5个对象的数组
(5) [{…}, {…}, {…}, {…}, {…}]
0: {answers: {…}, question: "some text", …}
1: {answers: {…}, question: "some text", …}
2: {answers: {…}, question: "some text", …}
3: {answers: {…}, question: "some text", …}
4: {answers: {…}, question: "some text", …}
在里面,答案对象是这样的:
answers: Array(4) // or Array (2) for boolean type answers
0: {answer: '1789', isCorrect: true, isClicked: false, answerId: '5Eh6V2AqoMdGlHadYdtXv'}
1: {answer: '1823', isCorrect: false, isClicked: false, answerId: 'V8yW9u2oHnZqlRjY-gR7A'}
2: {answer: '1756', isCorrect: false, isClicked: false, answerId: 'HNWO55rWQFQvrheGEjwAM'}
3: {answer: '1799', isCorrect: false, isClicked: false, answerId: 'o5BjyE3IJsAcWFEWQJnMA'}
基本思想是App组件拥有关于问题和答案的所有信息,并负责顶层的状态管理。在内部,有一个用于问题的Main组件,并且在其中有一个动态呈现的Answer组件,因为有两种类型的答案(具有两个答案可能性的布尔类型和具有四个答案可能性的multiple类型)。
<App>
<Main>
<Answer/>
</Main>
</App>
App内部的代码结构如下:
const [triviaData, setTriviaData] = useState([]) // data come from api fetch
function handleClick (id) {
// here I would like to get back the id derived from from props from the clicked answer
}
// here I'm mapping through the array of objects that I'm managing in my state and passing some props to the Main component
const triviaElements = triviaData.map(item => {
return (<Main
item={item}
key={item.id}
handleClick={() => handleClick()} //this is where I struggle /> )})
return (
<div> {triviaElements} </div>
)
现在主组件:
export default function Main(props) {
const triviaAnswers = props.item.answers.map(item => {
return (
<Answer
key={item.answerId}
answer={item.answer}
isCorrect={item.isCorrect}
answerId={item.answerId}
handleClick={() => handleClick(item.answerId)} // Problem: props.item.answers has not handleClick /> ) })
return(
<section className="main">
<h2 className="main--question">{props.item.question}</h2>
{triviaAnswers}
</section>
)
}
最后是答案部分:
export default function Answer(props) {
return (
<div className="answer" onClick={props.handleClick}>{props.answer}</div>
)
}
是否有一种精益的方式,通过多层函数并从答案组件获得正确的id ?非常感谢你的帮助。关于
通常,如果在父级和子级之间只有一个层次,并且在子组件中没有数组,只有一个元素,那么像这样的东西对我来说是有效的:
const elementsToRender = someArray.map(item => {
return (
<SomeComponent
handleClick={()=>handleClick(item.id)}
/> )
})
return (
{elementsToRender}
)
儿童
<div onClick={props.handleClick}>Some Element</div>
当您挂载Main
组件时,您错过了必须在App
中传递handleClick
的id
参数。
<Main
item={item}
key={item.id}
handleClick={(id) => handleClick(id)}
/>
简单地将handleClick
函数传递给handleClick
prop会简单得多,所以你不需要创建一个全新的箭头函数来处理它。
<Main
item={item}
key={item.id}
handleClick={handleClick}
/>
然后,在Main
组件本身中,您只需要引用props.handleClick
来实际调用其父组件定义的handleClick
函数。
export default function Main(props) {
const triviaAnswers = props.item.answers.map((item) => {
return (
<Answer
key={item.answerId}
answer={item.answer}
isCorrect={item.isCorrect}
answerId={item.answerId}
// Pass in the handleClick function from props
handleClick={() => props.handleClick(item.answerId)}
/>
);
});
return (
<section className="main">
<h2 className="main--question">{props.item.question}</h2>
{triviaAnswers}
</section>
);
}
当考虑通过许多React组件及其子组件传递处理程序/状态时,我建议查看React上下文(结合useReducer
)来一次管理多个组件的钻取状态。
文档:
- https://reactjs.org/docs/context.html
- https://reactjs.org/docs/hooks-reference.html usereducer