为了账号安全,请及时绑定邮箱和手机立即绑定

切换到功能组件与 useEffect 发生反应时出现问题

切换到功能组件与 useEffect 发生反应时出现问题

杨魅力 2024-01-03 16:36:35
我目前正在尝试将类组件(工作)更改为功能组件(不工作)。基本上,我的目标是使元素位于页面中心。编辑:如果任何人都可以发表评论ref={tc=>(this.treeContainer=tc)},这也会非常有帮助!我的班级组件(有效):/**  * Component returning a div containing a tree * Need to declare as class for ComponentDidMount()  */class CenterMe extends React.PureComponent {    state={}    /* Used to center the tree on render */    componentDidMount() {      const dimensions = this.treeContainer.getBoundingClientRect();      this.setState({        translate: {          x: 30,          y: dimensions.height / 2        }      });    }    /* Returns the actual tree content */    render(){      return(          <div class="treeWrapper" ref={tc => (this.treeContainer = tc)}>              <Tree                  translate = {this.state.translate}              />          </div>      );    }}我当前的功能组件看起来像这样并且不起作用:function CenterMe() {    const [state, setState] = useState({translate:{x:0,y:0}); // Added thanks to @jstu    /* Used to center the tree on render */    useEffect(()=> {      const dimensions = treeContainer.getBoundingClientRect();      setState({        translate: {          x: 30,          y: dimensions.height / 2        }      });    });    /* Returns the actual tree content */      return(          <div class="treeWrapper" ref={tc => (this.treeContainer = tc)}>              <Tree                  translate = {this.state.translate}              />          </div>      );}更具体地说,它抱怨 setState 和 treeContainer 没有定义。如果重要的话,树组件是从react-d3-tree导入的,翻译函数基本上按照字面意思做——它移动树。我认为问题主要集中在ref={tc=>(this.treeContainer=tc)},所以对此的解释也有帮助。太感谢了!
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

您需要使用添加两个钩子useRef来useState进行转换


function CenterMe() {

 const [translate, setTranslate] = useState({ x: 0, y: 0 });

 const treeContainer = useRef(null)


 /* Used to center the tree on render */

 useEffect(()=> {

  const dimensions = treeContainer.current.getBoundingClientRect();

  setTranslate({

      x: 30,

      y: dimensions.height / 2

  });

 }, []);


/* Returns the actual tree content */

  return(

      <div class="treeWrapper" ref={treeContainer}>

          <Tree

              translate={translate}

          />

      </div>

  );

}

useState 将替换基于类的组件中的 setState,如果您访问 treeContainer.current 键,则 useRef 将为您提供当前引用。


为了解释什么是 ref 部分,基本上,您的情况下的 ref 是引用 dom 节点,例如,如果您的树组件如下所示:


<div className="awesome-class">

 <p>Hi</p>

</div>

use ref 在这里所做的是,它会给你 dom 元素 ref,假设树组件像上面的例子一样,它看起来像这样。


    <div class="treeWrapper">

     <div className="awesome-class">

      <p>Hi</p>

     </div>

    </div>

通过 ref,您可以从 dom 获取元素,例如,在您的特定情况下,getBoundingClientRect将为您提供该特定元素的大小,正如您所看到的,这非常有用,因为您可以使用父组件中的子值。


查看完整回答
反对 回复 2024-01-03
?
元芳怎么了

TA贡献1798条经验 获得超7个赞

所以你似乎错过了状态挂钩。尝试这个


    function CenterMe() {

    const [state, setState] = useState({translate:{x:0,y:0}}); // Set an initial state

    const treeContainer = useRef(null);


        /* Used to center the tree on render */

        useEffect(()=> {

          const dimensions = treeContainer.current.getBoundingClientRect();

          setState({

            translate: {

              x: 30,

              y: dimensions.height / 2

            }

          });

        },[]);


        /* Returns the actual tree content */

          return(

              <div class="treeWrapper" ref={treeContainer}>

                  <Tree

                      translate = {state.translate}

                  />

              </div>

          );

    }

我没有测试过这个。但您缺少的是 useState 挂钩。我还注意到您的意思是实现 componentDidMount。所以你需要在最后传递一个空数组。这样它的行为就像 componentDidMount


查看完整回答
反对 回复 2024-01-03
?
汪汪一只猫

TA贡献1898条经验 获得超8个赞

好的,有几件事。Use state 返回一个可以使用语法 [] 解构的数组。像这样


    const [someName, setSomeName] = useState({

        translateX: 10,

        translateY: 20 

    })

您正在为 useState 提供一个匿名函数。不知道你能不能做到,以前没做过。


但请尝试我上面写的解决方案。通过调用该方法设置 translatioY 的值,然后在 Tree 组件中执行此操作。


<Tree  translate = {someName}/>

对于 ref 你必须使用 useRef() 钩子


查看完整回答
反对 回复 2024-01-03
  • 3 回答
  • 0 关注
  • 58 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信