javascript - 将带有 1 个 arg 的函数作为道具传递给子组件
问题描述
我正在尝试将setResponse()
函数作为 aprop
传递给子组件。该函数从子组件中获取一个参数(响应)并调用handleChange()
具有 3 个参数(父组件中可用的响应和 2 个参数)的函数。
我遇到的问题是我的setResponse
函数已传入但仅在第一次渲染时定义,即当我console.log()
在子组件函数中正确显示在第一次渲染但随后未定义时。我在下面提出了问题的代码,但在下面添加了更多上下文以防需要更多上下文。
更新:我想我可能需要在 FragmentWrapper 的 useEffect 中添加 setResponse 作为依赖项,但这会导致无限循环......
更新 2:制作了一个代码沙箱,用于玩 https://codesandbox.io/s/gracious-sunset-00hzl?file=/src/App.js
更新 3:我认为问题很可能出在父组件中。第一次渲染 FragmentWrapper 时,它具有正确的道具,因此父组件中必须发生某些事情(状态更改或其他?),这将导致 FragmentWrapper 的道具更改并触发重新渲染。也不确定为什么发生的任何事情都会导致 setResponse 变得未定义......
const DisplayQuestion = ({ answers, question, onChange }) => {
return React.createElement(question.component, {
setResponse: answer => {
handleChange(answer, question.id, answers)
}, // answer passed in from child, question.id and answers available in parent
})
}
下面是我尝试过的其他东西,但这显示了相同的行为(仅在第一次渲染时设置然后未定义)。
const DisplayQuestion = ({ answers, question, onChange }) => {
const setFunc = (answer) => {
handleChange(answer, question.id, answers)
}
return React.createElement(question.component, {
setResponse: setFunc,
},
}
上下文代码
- DisplayQuestion(调用 RadioQuestion)
const DisplayQuestion = ({ answers, question, onChange }) => {
const handleChange = (answer, id, answers) => {
onChange({ ...answers, [id]: answer })
}
return React.createElement(question.component, {
response: answers[question.id] ? answers[question.id] : null,
setResponse: answer => {
handleChange(answer, question.id, answers)
},
component: RadioQuestion,
...question, // these are other (passed in) props
})
}
- RadioQuestion(调用 FragmentWrapper)
export const RadioQuestion = props => (
<FragmentWrapper component={RadioFragment} {...props} />
)
- FragmentWrapper(调用 RadioFragment)
const FragmentWrapper = ({
questionText,
response,
setResponse,
component: Fragment
}) => {
const [value, setValue] = useState(response || '')
useEffect(() => {
console.log(setResponse) // prints correct 1st render then undefined
setResponse && setResponse(value)
}, [value])
const handleChange = setter => event => {
event && event.target ? setter(event.target.value) : setter(event)
}
const fragmentProps = { value, setValue, options, handleChange }
return (
<>
<Typography>{questionText}</Typography>
<Fragment {...fragmentProps} />
// Fragment=RadioQuestion as specified in DisplayQuestion
</>
)
}
- 无线电片段
export const RadioFragment = ({
value,
setValue,
options,
handleChange,
}) => {
return (
<FormControl>
<RadioGroup value={value} onChange={handleChange(setValue)} >
{options.map(option => (
<FormControlLabel value={option} control={<Radio />} />
))}
</RadioGroup>
</FormControl>
)
}
解决方案
推荐阅读
- html - 为什么 HTML 正文边距区域用正文的背景色填充?
- translation - Apache 缓存的翻译文件 PO/MO
- javascript - 未捕获的类型错误:无法读取 null 的属性“offsetTop”
- javascript - 缓存和未缓存 JavaScript 之间的 IE11 不同行为
- javascript - 当链接包含特殊字符时,Jquery 窗口滚动和位置固定侧边栏停止工作
- firebase - Firebase 身份验证 - 将用户导入为已禁用
- hibernate - repo.save() 上的 OutOfMemory 与 Pagable (小页面,但总元素很多)
- java - java.util.function.Function.identity 方法的实际用途是什么?
- javascript - Angular 6 多个动态 Charts.js 未显示
- sql-server - 我可以从给定月份的第一天找到昨天的日期吗?