繁体   English   中英

React 渲染与 UseState

[英]React render vs. UseState

我对此很陌生,无法真正弄清楚渲染是如何工作的 - 现在坚持使用 UseState :) -。 因为我看到很多人在使用它,所以我想就我做错了什么征求意见。 这里有 2 个示例,一个使用 UseState 效果很好,另一个使用 render 什么都不做,我添加了一些样式,所以它看起来对于任何尝试它的人来说都是可以接受的。

任何帮助表示赞赏,谢谢

// 使用状态

    const [newColor, setNewColor] = useState('green');
    
      useEffect(() => {
        setBorder()
      }, [newColor])
    
      function setBorder() {
        if (newColor === 'green') {
          document.getElementById('green').style.borderColor = "orange";
          document.getElementById('yellow').style.borderColor = "black";
          document.getElementById('red').style.borderColor = "black";
      }
      if (newColor === 'yellow') {
          document.getElementById('yellow').style.borderColor = "orange";
          document.getElementById('green').style.borderColor = "black";
          document.getElementById('red').style.borderColor = "black";
      }
      if (newColor === 'red') {
          document.getElementById('red').style.borderColor = "orange";
          document.getElementById('green').style.borderColor = "black";
          document.getElementById('yellow').style.borderColor = "black";
      }
      }
    
      const changeBg = () => {
        document.body.style.backgroundColor = newColor;
      }
    
      return (
        <div>
        <div style={{width: '240px', height: '88px', border: '3px solid black', 'borderRadius': '10px'}}>
        <div id="green" onClick={(e) => setNewColor(e.target.id)}    style={{width: '40px', height: '40px', background: 'green', border: '3px solid black', float: 'left', margin: '20px 0 0 30px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
        <div id="yellow" onClick={(e) => setNewColor(e.target.id)}   style={{width: '40px', height: '40px', background: 'yellow', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
        <div id="red" onClick={(e) => setNewColor(e.target.id)}      style={{width: '40px', height: '40px', background: 'red', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
        </div>
        <button onClick={changeBg}>SAVE</button>
        </div>
      );

// 使成为

    class Test1 extends Component {
        constructor(props) {
            super(props);
            this.state = {
                newColor: 'green'
            }
        }
    
        componentDidUpdate() {
            if (this.newColor === 'green') {
                document.getElementById('green').style.borderColor = "orange";
                document.getElementById('yellow').style.borderColor = "black";
                document.getElementById('red').style.borderColor = "black";
            }
            if (this.newColor === 'yellow') {
                document.getElementById('yellow').style.borderColor = "orange";
                document.getElementById('green').style.borderColor = "black";
                document.getElementById('red').style.borderColor = "black";
            }
            if (this.newColor === 'red') {
                document.getElementById('red').style.borderColor = "orange";
                document.getElementById('green').style.borderColor = "black";
                document.getElementById('yellow').style.borderColor = "black";
            }
        }
    
        render() {
    
            const changeBg = () => {
                document.body.style.backgroundColor = this.newColor;
              }
    
    
            return (
                <div>
                <div style={{width: '240px', height: '88px', border: '3px solid black', 'borderRadius': '10px'}}>
                <div id="green" onClick={(e) => this.state={newColor: e.target.id}}    style={{width: '40px', height: '40px', background: 'green', border: '3px solid black', float: 'left', margin: '20px 0 0 30px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
                <div id="yellow" onClick={(e) => this.state={newColor: e.target.id}}   style={{width: '40px', height: '40px', background: 'yellow', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
                <div id="red" onClick={(e) => this.state={newColor: e.target.id}}      style={{width: '40px', height: '40px', background: 'red', border: '3px solid black', float: 'left', margin: '20px 0 0 20px', 'borderRadius': '10px', cursor: 'pointer'}}></div>
                </div>
                <button onClick={changeBg}>SAVE</button>
                </div>
              );
        }
    }

首先,你永远不应该像你一样在react中直接更新 DOM。 在这两个示例中,您都在这样做。 第二个示例不起作用的原因, componentDidUpdate在更新发生时调用(例如状态更改或道具更改),这不会发生,因为您没有在第二个示例中调用setState 而是直接分配给this.state 如评论中所述,它也应该是this.state.newColor

在反应中解决这个问题的惯用方法是:

export default function App() {
  const [newColor, setNewColor] = React.useState('green');

  const changeBg = () => {
    document.body.style.backgroundColor = newColor;
  };

  return (
    <div>
      <div
        style={{
          width: '240px',
          height: '88px',
          border: '3px solid black',
          borderRadius: '10px',
        }}
      >
        {['green', 'yellow', 'red'].map((x) => (
          <div
            onClick={(e) => setNewColor(x)}
            style={{
              width: '40px',
              height: '40px',
              background: x,
              border: '3px solid black',
              borderColor: newColor === x ? 'orange' : 'black',
              float: 'left',
              margin: '20px 0 0 30px',
              borderRadius: '10px',
              cursor: 'pointer',
            }}
          ></div>
        ))}
      </div>
      <button onClick={changeBg}>SAVE</button>
    </div>
  );
}

虽然现在盒子没有很好地居中,因为当所有div都是手工写出时,第一个元素的边距不同。 但是现在我对所有这些都有相同的余量,因为我使用了一个循环。 我会让你来调整它。


*极少数情况下你可以,当说与 3rd 方库集成时,但在这种情况下,你应该确保 react 不会触及 DOM 的那部分。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM