尝试通过组件中的内部函数(setVisible)更新状态变量(“ visible”)。我检查了tutorıal并执行了相同的操作,但是在状态初始化后它没有更新。 Sandobx链接here。
当用户单击ShowModal按钮时,props.visible为true。但是函数组件中的visible值仍然为false。 (我已经在调试器上检查了内容)
代码:
import Modal from '../Helpers/AppModal'
class Streams extends Component {
constructor(props) {
super(props)
this.state = { showModal: false }
}
componentDidMount() {
this.props.getStreams()
}
showDeleteModal = (isShow) =>
{
this.setState({ showModal: isShow });
}
onClickBackdrop = () => {this.setState({ showModal: false });}
render() {
return (
<div>
<button onClick={()=> this.showDeleteModal(true)} className="btn btn-danger">Delete</button>
<Modal visible={this.state.showModal} onClickBackdrop={this.onClickBackdrop} />
</div>
)
}
}
AppModal.js:
const AppModal = (props) => {
const [visible, setVisible] = useState(props.visible)
useEffect(() =>{
setVisible(props.visible)
},[props.visible])
debugger
return (
<Modal visible={visible} fade={true} onClickBackdrop={props.onClickBackdrop}>
<div className="modal-header">
<h5 className="modal-title">{props.title}</h5>
</div>
<div className="modal-body">
{props.body}
</div>
<div className="modal-footer">
<React.Fragment>
<button type="button" className="btn btn-default" onClick={()=>setVisible(false)}>
Close
</button>
</React.Fragment>
</div>
</Modal>
)
}
答案 0 :(得分:1)
传递给useState
的参数只是初始状态。将prop
传递给它并不意味着state
将与props
同步。您可以设置效果以将这些更改反映到本地状态。
当前您的Modal
仅在本地状态下看到visible
,更改props
的值不会导致Modal
发生变化
//Inside child
useEffect(() =>{
setVisible(props.visible)
},[props])
为什么我应该在那里使用
props
而不是props.visible
?
您要告诉react
:
“嘿,每次这些值更改之一都会重新运行此效果。”
问题是React
在新旧Object.is
之间进行了浅比较(props
),每个render
都生成了一个新的props
对象首先就是触发效果的原因。
React不知道如何对嵌套的更改进行“反应”。这里真正改变的是props
,react不知道(也不在乎)props.visible
,将它作为依赖项传递与传递[]
实际上,将props
作为依赖项传递是没有用的,因为props
会更改每个渲染,因此您可以忽略依赖项数组,这会触发每个渲染器的效果
useEffect(() => {
setVisible(props.visible)
})
答案 1 :(得分:0)
visible
是布尔值。
尝试像这样更改您的呼叫方式setVisible
:
setVisible(false)
代替
setVisible({visible:false})
答案 2 :(得分:0)
如果这是一个拨动开关,则应执行以下操作:
onClick={() => setVisible(!visible)}
然后它将正确打开/关闭。
您可能希望通过以下方式更明确地设置初始值:
const [visible, setVisible] = useState(false);