所以,我有一个带反应路由器的站点,还有redux(下面的例子非常简化)
<Route path="/" component={ A } >
<Route path="/B" component={B} />
</Route>
A.jsx
class A extends Component {
render () {
const calculated_value_to_pass_down = FooBar()
return (
<div>
{React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
required_prop: calculated_value_to_pass_down
})
)}
</div>
)
}
}
export default A
B.jsx
class B extends Component {
render () {
return (
<div>
{ this.props.required_prop }
</div>
)
}
}
B.propTypes = {
required_prop: PropTypes.any.isRequired
}
export default B
但是,当我转到localhost:8080/B
时,我收到错误回溯:
Warning: Failed prop type: The prop `required_prop` is marked as required in `B`, but its value is `undefined`.
in A (created by RouterContext)
in RouterContext (created by Router)
in Router
in Provider
页面100%有效。并且错误在生产中没有发生,但我讨厌出现的错误。
页面实际上从未使用未定义的道具实际呈现,我甚至在调用render之前得到错误。
我知道我可以简单地删除.isRequired并且它会起作用,但这个想法闻起来很烂。
谢谢!
答案 0 :(得分:1)
我尝试了很多方法,但没有得到这个警告的原因。我可以猜到但不确定的一件事,cloneElement
按照DOC:
克隆并使用element作为起始返回一个新的React元素 点。结果元素将具有原始元素的道具 与新道具合并浅。新的孩子将取代 现有的孩子。
cloneElement
复制现有元素,可能是该组件首先被创建而没有道具然后被复制。
临时解决方案是,您可以使用defaultProps
来定义prop
的默认值,通过执行此操作,它不会抛出警告,如下所示:
B.defaultProps = {
required_prop: ''
}
答案 1 :(得分:0)
它不会出现在生产中,因为这些警告未在生产中显示/使用,但仍然存在错误。 (propTypes从生产代码中删除)
你的问题是A.jsx甚至在FooBar()完成之前渲染B.jsx,这意味着它发送的calculate_value_to_pass_down的值最初是未定义的,如果你的B.jsx组件不想拥有空道具那么解决方法是检查A.jsx中是否compute_value_to_pass_down未定义,如果未定义则不会渲染B.jsx组件。
<div>
{calculated_value_to_pass_down!==undefined? React.Children.map(this.props.children,
(child) => React.cloneElement(child, {
required_prop: calculated_value_to_pass_down
})
) : <div>LOADING</div>}
</div>
答案 2 :(得分:0)
感谢@ malayank-shukla的回答,我意识到问题出在代码的React.cloneElement
部分。
还有更多讨论:ReactTraining's Github Issues
似乎解决方案是:
.isRequired
React-Router v4有一个选项,允许您在路由上编写渲染属性而不是组件属性;但它对我的情况不起作用;或者我不理解它?
<Route
exact
path="/b"
render={routeProps => <B {...props} {...routeProps} />}
/>
我期待任何其他答案