Есть ли способ добавить прослушиватель событий в метод в компоненте A и иметь цель в отдельном компоненте - PullRequest
1 голос
/ 17 июня 2019

Я хочу добавить прослушиватель событий для компонента Table, чтобы каждый раз, когда я сохранял форму в компоненте Form методом saveForm(), я вызывал метод с именем showData() в компоненте Table .

Компонент формы


let persons = [];

if (JSON.parse(localStorage.getItem("personsForms")) !== null)
    persons = JSON.parse(localStorage.getItem("personsForms"));


saveForm(myForm) {
        persons.push(myForm);
        localStorage.setItem("personsForms", JSON.stringify(persons));

    }

Компонент таблицы


let persons;

let localStoragePersons = JSON.parse(localStorage.getItem("personsForms"));
persons = localStoragePersons !== null ? localStoragePersons : [];


    showData() {
        let table = document.getElementById('editableTable');
        let x = table.rows.length;
        while (--x) {
            table.deleteRow(x);
        }
        let i = 0;

        ...........
    }

Ответы [ 2 ]

0 голосов
/ 17 июня 2019

С React DOCS :

Помните: React - это все о односторонний поток данных вниз поиерархия компонентов. Может быть не сразу понятно, какой компонент должен принадлежать какому состоянию.Это часто самая сложная часть для понимания новичками, поэтому следуйте этим шагам, чтобы понять это:

Односторонний поток данных React предназначен для сверху вниз ,родитель-ребенок.То, как вы предлагаете, будет братья и сестры, которые будут из стороны в сторону вместо сверху вниз .Это анти-шаблон.

Вы можете настроить иерархию компонентов следующим образом:

Посмотрите, что вам подходит.

function App() {
  
  function doSomethingApp(formValue) {
    console.log('Do something from App!');
    console.log('Form value is: ' + formValue);
  }
  
  return(
    <React.Fragment>
      <Table/>
      <Form
        doSomethingApp={doSomethingApp}
      />
    </React.Fragment>
  );
}

function Table(props) {
  
  function doSomethingTable(formValue) {
    console.log('Do something from Table!');
    console.log('Form value is: ' + formValue);
  }
  
  return(
    <div>I am Table</div>
  );
}

function Form(props) {
  const [value,setValue] = React.useState('');
  return(
    <React.Fragment>
      <div>I am Form</div>
      <input type='text' value={value} onChange={()=>setValue(event.target.value)}/>
      <div>
        <button onClick={()=>props.doSomethingApp(value)}>Do something from App</button>
      </div>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

SNIPPET: ВНИМАНИЕ, ЭТО АНТИ-УЗОР

Хотя я бы не рекомендовал этосовсем.Это рабочий пример запрошенного вами анти-паттерна.

У Sibling1 есть useEffect, который обновляет состояние общего родителя App с помощью метода showData.Всякий раз, когда showData изменяется, эффект запускается снова и обновляется.showData является запомненным обратным вызовом.Вы можете добавить массив зависимостей, чтобы обновлять этот запомненный обратный вызов при изменении какой-либо другой переменной.

Источник: Справочник по API хуков

function App() {

  const [sibling1Method,setSibling1Method] = React.useState({method: null});
  

  return(
    <React.Fragment>
      <Sibling1
        setSibling1Method={setSibling1Method}
      />
      <Sibling2
        sibling1Method={sibling1Method}
      />
    </React.Fragment>
  );
}

function Sibling1(props) {
  
  const showData = React.useCallback((formValue) => {
    console.log('A click from Sibling2 is triggering a Sibling1 Method');
  },[]);
  
  React.useEffect(()=>{
    props.setSibling1Method({method: showData});
  },[showData]);
  
  return(
    <div>Sibling 1 </div>
  );
}

function Sibling2(props) {
  return(
    <React.Fragment>
      <span>Sibling 2 </span>
      <button onClick={()=>props.sibling1Method.method()}>Click</button>
    </React.Fragment>
  );
}

ReactDOM.render(<App/>,document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
0 голосов
/ 17 июня 2019

Предполагается, что компонент Table является родительским компонентом компонента Form.

Передайте метод в качестве опоры компоненту формы и вызовите его для доступа к реквизиту (this.props.parentMethod ())

...