ReactJS - Ребенок не может получить доступ к родительскому состоянию после обновления - PullRequest
0 голосов
/ 15 марта 2020

У меня есть input field в дочернем компоненте, который предварительно заполняется из значения состояния родителя.

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

Состояние моего родителя:

  const [blockList,setBlockList] = useState({
    "0":{
      type:"loading",
      content:{
        'title':"placeholder_title",
        'description':"placeholder_description"
      }
    },
    "1":{
      type:"description",
      content:{
        'title':"placeholder_title",
        'description':"placeholder_description"
      }
    },
    "2":{
      type:"skills_and_requirements",
      content:{
        'title':"",
        'description':""
      }
    },
  })

Переданная функция ребенку:

const _getBlockContent = (
  currentBlockKey, 
  contentKey, 
  returnedContent
) => {
  setBlockList(blockList[currentBlockKey].content[contentKey] = returnedContent)
}

Что я передаю ребенку:

  return (    
      <Child
        currentBlock={blockList[selectedBlock]} // (i.e. selectedBlock = '1')
        _getBlockContent={_getBlockContent}
        currentBlockKey={selectedBlock} // (i.e. selectedBlock = '1')
      /> )

Теперь, когда я сохраняю входные данные в потомке и использую функцию _getBlockContent, чтобы обновить состояние моего родителя, это приводит к разрыву моего Ребенка.

TypeError: props.currentBlock.content is undefined

Полный ребенок (черновик JS):

const EditorPanel = (props) => {

  //receives the block from the parent. The block type will define the advice and other static elements of the pannel. The block content will define what to include in the input and editor fields.
  //This function should be passed to the editor and update the block content. 
  const _getEditorContent = (contentKey, returnedContent) => {
    console.log("contentKey is: %s", contentKey);
    console.log("returnedContent is: %s", returnedContent);
    props._getBlockContent(props.currentBlockKey,contentKey, returnedContent)
  }

  return(
    <div className="edit_panel">
      <div className="edit_panel_container">
        <h2>Description</h2>
        <h3>Title</h3>
        <MyEditor 
          contentKey={'title'}
          contentValue={props.currentBlock.content['title']}
          _getEditorContent={_getEditorContent}
        />
        <p>Title of this section should be eiusmod  dolor sit amet, consectetur.</p>
        <h3>Description</h3>
        <MyEditor 
          contentKey={'description'}
          contentValue={props.currentBlock.content['description']}
          _getEditorContent={_getEditorContent}
        />

        <p
        >Title of this section should be eiusmod  dolor sit amet, consectetur.</p>
        <p>Title of this section should be eiusmod  dolor sit amet, consectetur.</p>
      </div>
    </div>
  );
};


class MyEditor extends React.Component {
  constructor(props) {
    super(props);
    //this.state = {editorState: EditorState.createEmpty()};
    this.state = {editorState: EditorState.createWithContent(
      stateFromHTML(props.contentValue)
    )};
    this.onChange = editorState => {
      this.setState({editorState});
      //this.returnEditorHTML()
    }
    this.handleKeyCommand = this.handleKeyCommand.bind(this);
    this.focus = () => this.editor.focus();
    this.returnEditorHTML = editorState => {
      const content = stateToHTML(this.state.editorState.getCurrentContent());
      props._getEditorContent(props.contentKey,content);
    };
  }



  handleKeyCommand(command, editorState) {
    const newState = RichUtils.handleKeyCommand(editorState, command);

    if (newState) {
      this.onChange(newState);
      return 'handled';
    }

    return 'not-handled';
  }

  _onBoldClick() {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
  }

  _onItalicClick() {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'ITALIC'));
  }

  _onUnderlineClick() {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'UNDERLINE'));
  }

  render() {
    return (
      <div>
        <div className="draft_input">
          <Editor 
            editorState={this.state.editorState}
            handleKeyCommand={this.handleKeyCommand}
            onChange={this.onChange} 
          />
        </div>
        <button onClick={this._onItalicClick.bind(this)}>I<i className="fas fa-bold"></i></button>
        <button onClick={this._onBoldClick.bind(this)}>B</button>
        <button onClick={this._onUnderlineClick.bind(this)}>U</button>
        <button onClick={this.returnEditorHTML}>save</button>
        <div></div>
      </div>
    );
  }
}

1 Ответ

0 голосов
/ 15 марта 2020

Я вижу что-то.

Исходя из вашего имени, _getBlockContent(..) предназначено для получения состояния. Обратите внимание: setBlockList(..) не предназначен для чтения состояния, он используется только для обновления состояния. Для чтения состояния вы можете напрямую использовать blockList в компоненте вашей функции _getBlockContent(..), как показано ниже.

    return blockList[currentBlockKey].content[contentKey];

Кроме того, чтобы активно воспроизвести вашу ошибку на моем конце, вы можете поделиться ссылкой на github или что-то, содержащее все компоненты в вашей логике c (включая et c)?

...