关于React你必须知道的3个错误用法。

发布时间:2024年01月13日

1. 你知道如何使用“&&”吗?

在React程序中,我经常使用“&&”运算符来决定是否显示内容,如下所示:

我的组长: “你不知道&&运算符的特性吗?当请求还没有成功返回时,会直接渲染“0”。”

我并不信服, 因为我一直都是这样编写代码,从未出过错。为了证明老板错了,我写了下面的示例

我的天!组长是对的,页面开始是显示0,3秒后才显示列表。

为什么?

提示(来自 MDN):“逻辑与(&&)运算符(逻辑连词)对一组布尔操作数将只有当所有操作数都为真时才为真。否则,它将为假。”

更一般地说,该运算符返回从左到右评估时遇到的第一个假值操作数的值,或者如果它们都是真值,则返回最后一个操作数的值。

几个例子

const x1 = 0
const x2 = 'fatfish'
const x3 = 1
const x4 = 'medium'
console.log(x1 && x2) // 0
console.log(x3 && x4) // medium

现在我终于理解为什么那样编写代码会导致错误了。原因如下:

list.length && <List list={ list } /> 
0 && <List list={ list } /> // 0

如何解决?

我找到了三种解决这个问题的方法。希望你不要犯我的错误。祝你好运。

// 1. Convert list.length to boolean
!!list.length && <List list={ list }/>
  
// 2. Use ternary expressions and null
list.length ? <List list={ list }/> : null

// 3. Controlled by specific logic
list.length >= 1 && <List list={ list }/>

2. “props.children”的奇怪行为

我猜你写过类似的代码。 当向<Container />组件传递内容时,“children” 将显示。如果没有,将显示一个空工具提示。 如下所示:

const Container = ({ children }) => {
  if (children) {
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}

我的老板:“你必须谨慎使用“children”属性,它会导致逻辑异常!像下面这种情况。”

1. 空列表数据

你认为这个例子会显示什么——“空”?

不幸的是,答案是另一个。 朋友们,我们必须非常小心地使用 props.children。 否则,老板可能会扣掉你的工资。

const Container = ({ children }) => {
  if (children) {
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}
const App = () => {
  const [ list, setList ] = React.useState([])
  
  return (
    <Container>
      {
        list.map((name) => {
          return <div className="name-item">{ name }</div>  
        })
      }
    </Container>
  )
}
ReactDOM.render(<App />, document.getElementById('app'))

为什么?

让我们在“Container”组件中添加一行代码,并尝试打印children是什么!

const Container = ({ children }) => {
  console.log(children, 'children')
  // ...
}

是的,你猜对了。 此时,“children”是一个空数组,所以显示“children的内容是:”而不是“空”

如何解决?

使用 React.Children.toArray 来解决这个问题将非常容易,然后你会看到显示“空”。 所以,如果你真的需要将子代用作条件判断,我建议你使用这种方法!

const Container = ({ children }) => {
  // if (children) {
  // Pay attention here
  if (React.Children.toArray(children).length) {  
    return (
      <div className="children-container">
        <p>The content of children is:</p>
        { children }
      </div>
    ) 
  } else {
    return (
      <div className="empty">empty</div>
    )
  }
}

3. 关于挂载和更新的问题

在React中通过状态切换组件是很常见的,但这个小东西也会让你困惑。

在下面的代码中,当你切换 name 的值时,你认为一个 Demo 组件将被卸载并且另一个将被挂载吗?

lass Demo extends React.Component {
  componentDidMount() {
    console.log('componentDidMount', this.props.name);
  }
  componentDidUpdate() {
    console.log('componentDidUpdate', this.props.name);
  }
  
  render () {
    return (
      <div>
        { this.props.name }
      </div>
    )
  }
}
const App = () => {
  const [ name, setName ] = React.useState('fatfish')
  const onClick = () => {
    setName(name === 'fatfish' ? 'medium' : 'fatfish')
  }
  return (
    <div className="app">
      {
        name === 'fatfish' ? 
          <Demo name={ name } /> : 
          <Demo name={ name } />
      }
      <button onClick={ onClick }>click</button>
    </div>
  )
}
ReactDOM.render(<App />, document.getElementById('app'))

我录制了一个短gif来给你真相,你也可以通过 CodePen 尝试它。

为什么?

尽管我们写了两个 Demo 组件并且假设它们会分别挂载和更新,但 React 认为它们是相同的组件,所以 componentDidMount 只会执行一次。

如何解决?

但是当我们想写两个相同的组件但传递不同的参数时,我们该怎么做呢?

是的,你应该给这两个组件添加不同的 ‘keys’,这样 React 会认为它们是不同的组件。componentDidMount 也会各自执行。

让我们试试

//...
// Pay attention here
name === 'fatfish' ? <Demo key="1" name={ name } /> : <Demo key="2" name={ name } />
//...

最后

感谢阅读。 期待你的关注和阅读更多高质量文章。

在这里插入图片描述

文章来源:https://blog.csdn.net/weixin_42429220/article/details/135577345
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。