当前位置:优学网  >  在线题库

React的Class组件不能及时获取到更新后的state咋办?

发表时间:2022-06-26 22:43:25 阅读:113

我有一段这样的代码

Modal.confirm({
    tilte: "title",
    content: (
        <>
            <input onChange={
                () => this.setState({ A: true });
            }></input>

            this.state.A && <div>这是一段文字</div>
        </>
    )
})

目的是,在 input 变化后, 就会显示 <div>这是一段文字</div>,但是发现状态A变化后不能及时拿到,导致div里的内容一直不显示出来,请问要怎么修改呢?

🎖️ 优质答案
    1. 问题:
      你是使用命令式(Modal.confirm)的展示Modal的,state变更时并不会触发Modal重新渲染。
    2. 解决方案:

      • 可以改成声明式的方式展示Modal,比如:
      class Test extends React.Component {
        state = {
       A: false,
       visible: false
        };
        handleClick = () => {
       this.setState({ visible: true });
        };
        render() {
       const { visible } = this.state;
       return (
         <>
           <Button onClick={this.handleClick}>Show Modal</Button>
           <Modal
             visible={visible}
             onCancel={() => this.setState({ visible: false })}
           >
             <input onChange={() => this.setState({ A: true })}></input>
             {this.state.A && <div>这是一段文字</div>}
           </Modal>
         </>
       );
        }
      }
      • 2.2 把Modal.confirm展示的内容抽成一个组件
      class ConfirmContent extends React.Component {
        state = {
       A: false
        };
        render() {
       return (
         <>
           <input onChange={() => this.setState({ A: true })}></input>
           {this.state.A && <div>这是一段文字</div>}
         </>
       );
        }
      }
      
      //
      Modal.confirm({
        tilte: "title",
        content: <ConfirmContent />
      });
      //
    3. 根本原因:React的更新粒度是一颗fiber树,像这种命令式的方法往往会重新创建一颗fiber树(在内部会调用createRoot,或者ReactDom.render),你的问题就出在了用一个在fiber树1(你自己在App.tsx中创建的fiber树)上的fiber触发了更新操作,而不是用fiber2上的fiber触发的更新(你用confirm创建出来的fiber树),一个组件对应于一个fiber,他们被传入了一个createRoot或者ReactDom.render后他就属于那个fiber树了
  • 这个得这么写才行,用() =>

    Modal.confirm({
        tilte: "title",
        content: (
            <>
                <input onChange={() =>
                    this.setState({ A: true });
                }></input>
    
                this.state.A && <div>这是一段文字</div>
            </>
        )
    })

    希望能帮助到你。

  • 相关问题