4 очень полезных совета по React.

1. Не забудьте удалить прослушиватель, когда компонент размонтируется.

Нам часто нужно прослушивать события клавиатуры, мыши и т. д. в useEffect из React. Но мы часто забываем их удалить.

const windowScroll = () => {
  console.log('scroll')
}

useEffect(() => {
  window.addEventListener("scroll", windowScroll, false)
}, [])

Да, когда мы вернемся к этому компоненту, событие scroll будет снова прослушиваться.

Другими словами, мы можем связать тысячи windowScroll функций с window. Это приведет к утечкам памяти и неожиданному поведению слушателей.

Пожалуйста, не забудьте удалить прослушиватель, когда компонент размонтируется.

const windowScroll = () => {
  console.log('scroll')
}

useEffect(() => {
  window.addEventListener("scroll", windowScroll, false)
  return () => {
    window.removeEventListener('scroll', windowScroll, false)
  }
}, [])

2. Пожалуйста, используйте 0 осторожно, это дьявол

Возможно, вы написали код, подобный приведенному ниже, что он отображает? Или вообще ничего не показывает?

const App = () => {
  const [ list, setList ] = useState([])

  return (
    list.length && (
      <div className="list">
        {list.map((name) => {
          return <div className="item">{name}</div>
        })}
      </div>
    )
  )
}

Я не думаю, что с этим кодом что-то не так! Но он показывает 0. Может ли это быть ОШИБКОЙ React?

const i = 0
const b = 'fatfish'

console.log(i && b)

Я ошибся, это не баг React, он полностью соответствует синтаксису JavaScript.

Чтобы избежать неправильного отображения 0, нам нужно использовать следующие три способа решения этой проблемы.

// 1. Controlled by specific logic
list.length >= 1 && <Component list={list} />
// 2. Convert list.length to boolean
!!list.length && <Component list={list} />
// 3. Use ternary expressions and null
list.length ? <Component list={list} /> : null

3. Как легко передать true дочерним элементам

Нам часто нужно передать логическое значение компоненту, когда мы его вызываем, например, явно передать true.

const Child = ({ showNav }) => {
  return !!showNav && <Nav />
}

const Parent = () => {
  return <Child showNav = { true } />
}

На самом деле вам просто нужно передать свойство showNav. Оба они имеют одинаковый эффект.

const Child = ({ showNav }) => {
  return !!showNav && <Nav />
}

const Parent = () => {
  return <Child showNav/>
}

4. Пожалуйста, не используйте больше props.children

Каков результат этого кода, пожалуйста? Он пустой?

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

const App = () => {
  const [ list, setList ] = useState([])
  
  return (
    <Container>
      {
        list.map((name) => {
          return <div className="item">{ name }</div>  
        })
      }
    </Container>
  )
}

К сожалению, ответ «Дети это:». Боже мой! Почему это?

На самом деле children в настоящее время является пустым массивом, поэтому обязательно будет отображаться «Дети:». Как решить эту проблему? React.Children.toArray спасет нас

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

Дополнительные материалы на PlainEnglish.io.

Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .

Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.