简体   繁体   English

有什么方法可以在组件A的方法中添加事件侦听器,并将目标放置在单独的组件中

[英]Is there any way to add an event listener in a method in a component A, and have the target in a separate component

I want to add an event listener to the component Table so that every time I save a form in the component Form by the method saveForm() I call a method called showData() in the component Table . 我想一个事件监听器添加到组件Table 。每次我在组件保存表单Form通过该方法saveForm()我称之为叫方法showData()中的成分Table

Form Component 表单组件


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));

    }

Table Component 表组件


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;

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

Assuming that Table component is the parent component of Form component. 假设Table组件是Form组件的父组件。

Pass the method as a prop to Form Component and call it accessing to the props (this.props.parentMethod()) 将方法作为道具传递给表单组件,并调用它访问道具(this.props.parentMethod())

From React DOCS : React DOCS

Remember: React is all about one-way data flow down the component hierarchy. 记住: React是关于组件层次结构中的单向数据流。 It may not be immediately clear which component should own what state. 可能尚不清楚哪个组件应拥有什么状态。 This is often the most challenging part for newcomers to understand, so follow these steps to figure it out: 对于新手来说,这通常是最具挑战性的部分,因此请按照以下步骤进行操作:

React's one-way data flow is meant to be top-down , parent-child. React的单向数据流是自上而下的父子流。 The way you're suggesting would be sibling-to-sibling, which would be side-to-side instead of top-down . 你所建议的方法是兄弟对兄弟,这将是一侧到另一侧 ,而不是自上而下 This is an anti-pattern. 这是一种反模式。

You can set up your component hierarchy like this: 您可以像这样设置组件层次结构:

See it that works for you. 看到适合您的产品。

 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: ATTENTION, THIS IS AN ANTI-PATTERN SNIPPET:注意,这是一个反模式

Although I wouldn't recommend this at all. 尽管我完全不建议这样做。 This is a working example with the anti-pattern you requested. 这是您请求的反模式的有效示例。

Sibling1 has a useEffect which updates a state on the common parent App with its method showData . Sibling1具有useEffect ,它使用showData方法更新公共父App上的状态。 Whenever showData changes, the effect is run again and keeps it updated. 每当showData更改时,效果都会再次运行并保持更新。 showData is a memoized callback. showData是一个记住的回调。 You can add a depedency array to update this memoized callback whenever some other variable changes. 每当其他变量发生更改时,您都可以添加一个依赖数组来更新此通知的回调。

Source: Hooks API Reference 来源: Hooks 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM