Как предотвратить повторное рендеринг - PullRequest
1 голос
/ 13 апреля 2020

Я сделал этот Компонент, он посылает реквизиты на флажок и диапазон компонентов. Когда я тестировал функциональность этих 2-х компонентов, я видел, что когда я сделал изменение в компоненте диапазона, флажок также перерисовывался, но он не менялся и не менялся при смене флажка. *

  • Когда я изменяю диапазон, второй также перерисовывает

        const GeneratePassword = () => {
          // Checkbox
          const [state, setState] = useState({
            Symbols: false,
            capiatalLetters: false,
            digits: false,
          })
    
          const handleChange = (e) => {
            setState({ ...state, [e.target.name]: e.target.checked })
          }
    
          // Range
    
          const [value, setValue] = useState(8)
    
          const handleInputChange = (event) => {
            setValue(event.target.value === '' ? '' : Number(event.target.value))
          }
    
          const handleBlur = () => {
            if (value < 8) {
              setValue(8)
            } else if (value > 30) {
              setValue(30)
            }
          }
    
          return (
            <Comp.StyledCheckboxContainer>
              <Comp.CheckboxBorder>
                <CheckboxContainer isCheck={handleChange} option={state} />
                <Range
                  value={value}
                  handleInputChange={handleInputChange}
                  handleBlur={handleBlur}
                  setValue={setValue}
                />
              </Comp.CheckboxBorder>
            </Comp.StyledCheckboxContainer>
          )
        }
    
        export default GeneratePassword
    

Ответы [ 2 ]

0 голосов
/ 13 апреля 2020

Компоненты обновляются при каждом изменении состояния, потому что их реквизиты меняются. Функции, которые используются как обратные вызовы, должны быть запомнены, чтобы предотвратить это. То, что некоторые из них полагаются на текущее состояние, является проблемой, им нужно использовать функцию обновления, чтобы не ссылаться на устаревшее состояние:

  const handleChange = useCallback((e) => {
    setState((state) => ({ ...state, [e.target.name]: e.target.checked }))
  }, [])

  ...

  const handleInputChange = useCallback((event) => {
    setValue(event.target.value === '' ? '' : Number(event.target.value))
  }, [])

  ...

  const handleBlur = useCallback(() => {
   setValue(value => {
    if (value < 8) {
      return 8
    } else if (value > 30) {
      return 30
    }
   })
  }, [])

На этом этапе дочерние компоненты могут предотвращать ненужные повторные отображения. Если они этого не делают, они должны быть дополнительно завернуты в React.PureComponent или React.memo. Для произвольного компонента оболочка может быть:

OptimizedComp = React.memo(props => <Comp {...props} />);
0 голосов
/ 13 апреля 2020

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

const handleInputChange = (event) => {
    setValue(event.target.value === '' ? '' : Number(event.target.value))
}

Вкл. каждый рендер handleInputChange получает новое значение, новую ссылку. Вам нужно использовать React.useCallbak(), чтобы сохранить одинаковое значение для всех рендеров

const handleInputChange = React.useCallback((event) => {
    setValue(event.target.value === '' ? '' : Number(event.target.value))
}, []);
...