首页 > 解决方案 > 反应钩子,不能通过道具更新状态

问题描述

试图通过组件中的内部函数(setVisible)更新状态变量('visible')。我检查了教程并做了同样的事情,但在状态初始化后它没有更新。Sandobx 链接在这里

当用户单击 ShowModal 按钮时,props.visible 为真。但是功能组件中可见的值仍然是错误的。(我已经检查了调试器上的内容)

代码:

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>
  )
}

标签: reactjsreact-hooks

解决方案


传递给的参数useState只是初始状态。将 a 传递prop给它并不意味着state将与props. 您可以设置效果以将这些更改镜像到您的本地状态。

目前您Modal只能visible从本地状态看到,更改props值不会导致Modal更改

//Inside child
useEffect(() =>{
    setVisible(props.visible)
},[props])

为什么我应该使用props而不是props.visible那里?

依赖数组的存在是为了保持同步性,你说react

“嘿,每次其中一个值更改时都会重新运行此效果。”

问题是在 old 和 new 之间React执行浅比较 ( ) ,每次生成一个新对象,这首先会触发你的效果。Object.ispropsrenderprops

React 不知道如何对嵌套的更改做出“反应”。这里真正改变的是props,react 不知道(也不关心)props.visible,将其作为依赖项传递与传递相同[]

实际上作为依赖传递props是没有用的,因为props每次渲染都会改变你可以省略依赖数组,这将触发每个渲染的效果

useEffect(() => {
    setVisible(props.visible)
})

推荐阅读