Компонент обновляется только когда обернут в `div` - PullRequest
0 голосов
/ 20 марта 2020

Я столкнулся с проблемой, когда мой компонент обновляется только в div.

У меня есть switch statement для рендеринга разных версий ребенка. Кажется, что все работает, когда я обертываю свой второй случай в div, но если этого div нет, он не работает, как ожидалось. Кажется, что _getCurrentInputState и selectedBlock не обновляются должным образом.

const Parent= () => {

    {/* ... */}

    const _renderEditorPanel = () =>{
        const currentBlockType = blockList[selectedBlock].type
        switch(currentBlockType){
          case 'description': return (
            <EditorPanel 
              currentBlockType={'description'}
              selectedBlock={selectedBlock}
              _getBlock={_getBlock}
              _getCurrentInputState={_getCurrentInputState}
              _setCurrentInputState={_setCurrentInputState}
            />
          )
          case 'skills_and_requirements': return (
            <div>  {/* <<<<<<<<<<<<<<<<<<<<<<<< This is needed to really update the child?
            */}
            <EditorPanel 
              currentBlockType={'skills_and_requirements'}
              selectedBlock={selectedBlock}
              _getBlock={_getBlock}
              _getCurrentInputState={_getCurrentInputState}
              _setCurrentInputState={_setCurrentInputState}
            />
            </div> {/* <<<< and this.*/}
          );
          default: return (
            <EditorPanel 
              currentBlockType={'default'}
              selectedBlock={selectedBlock}
              _getBlock={_getBlock}
              _getCurrentInputState={_getCurrentInputState}
              _setCurrentInputState={_setCurrentInputState}
            />
          );
      }
      }


      return (    
        <StyledJobEditor>
          {_renderEditorPanel()}    
          <div className="preview_panel">
            <div>
            <button onClick={
              () => setSelectedBlock("1")
            }>1</button>
            <button onClick={() => setSelectedBlock("2")}>2</button>
            <button onClick={() => setSelectedBlock("0")}>0</button>
            </div>

              {/*
                The sidebar will be an arraw of block. We should expect to use the .map function here.
              */}

          </div>
        </StyledJobEditor>
      );
    }

Ответы [ 2 ]

1 голос
/ 20 марта 2020

Я полагаю, что причина, по которой вы это видите, в том, что реакция не может сказать, что она должна смонтировать новый экземпляр того же компонента. Изменяя один, чтобы быть обернутым в div реакция видит, что он отличается и перемонтирует все. В противном случае, он просто воспринимает это как изменение реквизита.

Не видя реализации EditorPanel, я не могу больше понять, но я бы предположил, что ваши неизмененные реквизиты устанавливаются только один раз на монтирование или что-то в этом роде. аналогично.

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

switch (currentBlockType) {
  case 'description': return (
    <EditorPanel
      key="description"                 // Add this
      currentBlockType={'description'}
      selectedBlock={selectedBlock}
      _getBlock={_getBlock}
      _getCurrentInputState={_getCurrentInputState}
      _setCurrentInputState={_setCurrentInputState}
    />
  )
  case 'skills_and_requirements': return (
    <EditorPanel
      key="skills_and_requirements"      // Add this
      currentBlockType={'skills_and_requirements'}
      selectedBlock={selectedBlock}
      _getBlock={_getBlock}
      _getCurrentInputState={_getCurrentInputState}
      _setCurrentInputState={_setCurrentInputState}
    />
  )
  default: return (
    <EditorPanel
      key="default"                      // Add this
      currentBlockType={'default'}
      selectedBlock={selectedBlock}
      _getBlock={_getBlock}
      _getCurrentInputState={_getCurrentInputState}
      _setCurrentInputState={_setCurrentInputState}
    />
  )
0 голосов
/ 20 марта 2020

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

const RenderEditorPanel = () => {
        const currentBlockType = blockList[selectedBlock].type || 'default';
        return (
        <EditorPanel 
              currentBlockType={currentBlockType}
              selectedBlock={selectedBlock}
              _getBlock={_getBlock}
              _getCurrentInputState={_getCurrentInputState}
              _setCurrentInputState={_setCurrentInputState}
            />
        )
      }

Кроме того, когда мы используем этот компонент, он должен быть как ниже

<RenderEditorPanel />
...