如何将事件从子组件传递到父组件,再传递回React中的另一个子组件

时间:2020-10-23 14:48:27

标签: javascript reactjs

例如,让我说我在React中有三个组件,一个应用程序(父组件),一个按钮组件和一个用于显示某些内容的组件,可以是任何东西都没有关系。可以说,在按钮组件被激活的情况下,我如何将信息(即事件实际发生)传递给App父组件,再传递给另一个子组件,以使其知道发生了某些消息的特定事件呢? >

4 个答案:

答案 0 :(得分:0)

这就是我将如何使用钩子来解决这个问题:

const Parent=(props)=>{
 [eventHappend,setEventHappend]=useState(false)
 return (
  <div>
     <Child1 setEventHappend={setEventHappend} />
     <Child2 eventHappend={eventHappend} />
  </div>
)
}


const Child =({setEventHappend})=>{
 return (
  <div>
     <button onClick={e=>setEventHappend(true)} > click me 1 </button>
  </div>
)
}


const Child2 =({eventHappend})=>{
 
 return (
  <div>
     <button onClick={e=>{/* some code*/ }} > {eventHappend?'event happend':'event didnt happen yet '} </button>
  </div>
)
}

答案 1 :(得分:0)

有多种方法可以实现此传递状态,以作为子元素的道具(必须先于其他方法),上下文或使用具有存储的redux。

一般来说。 React具有一种单向数据流。就像在父级中一样,它将保持状态并将其传递给子级元素。

App包含状态buttonClick,其中包含有关事件的信息。

const App = () => {
const [ buttonClick, setButtonClick] = React.useState(false);
const messageToBeDispalyed = "The button has been clicked"
return (
<div>
<CustomButton setEventHappened={setButtonClick} />
<DisplayText  value = {buttonClick ? messageToBeDispalyed : ""} />
</div>
 )
}

const CustomButton = (props) =>{
return <button onClick={(e)=>props.setEventHappened(true)} >  Click Me </button>
}

const DisplayText = (props) => {
return <h1> {props.value} </h1>
}


答案 2 :(得分:0)

其他答案相似,但是您需要将方法从父级传递给子级以更新状态。但是请注意,这样做会导致父母的所有孩子都重新投降。

const Parent = () => {
  const [state, setState] = React.useState(false);

  const handleClick = value => {
    setState(value);
  };

  return (
    <Child state={state} handleClick={handleClick} />
    <OtherChild isTrue={state} /> // this component needs data changed by <Child />
  )
};
const Child = props => {
  const {state, handleClick} = props;

  return (
    <button onClick={() => handleClick(!state)} >click me</button>
  );
};

通过这种方式,父级独自处理状态更改并将该方法提供给子级。

答案 3 :(得分:0)

正如@Loveen Dyall和@Shruti B提到的那样,您可以使用RXJS来实现更模块化的方法,尽管RxJS通常被认为与Angular项目一起使用,但它是一个完全独立的库,可以与其他JavaScript框架(如React)一起使用和Vue。

当将RxJS与React一起使用时,组件之间进行通信的方式是使用Observable和Subject(这是一种可观察的对象),在这里我不会过多地介绍可观察的工作原理,因为它是总的来说,这是我们感兴趣的两种方法:Observable.subscribe()和Subject.next()。 了解有关RXJS和Observables的更多信息:https://blog.logrocket.com/understanding-rxjs-observables/
Observable.subscribe() React组件使用observable订阅方法来订阅发送到Observable的消息。

Subject.next() 下一个主题方法用于将消息发送到可观察对象,然后将消息发送到该可观察对象的所有订阅者(也称为观察者)。


在此用例中,这是您的实现方式: 这称为服务,您可以将此文件放入服务文件夹
import { Subject } from 'rxjs';
const subject = new Subject();

//here where sending { event: eventTitle } , that way you can listen to diffrent events , for example 'INCREMENTED' you could even send values 
export const eventsService= {
    sendEvent: eventTitle => subject.next({ title: eventTitle }),
    getEventNotification: () => subject.asObservable()
};

在您的Child 1组件中,如果您使用的是类组件,您将订阅useEffect或compoentDidMount中的可观察对象:

import { eventsService} from '../services';
const Child1 =()=>{
  const [child2EventFired,setChild2EventFired]=useState(false)
  useEffect(()=>{
      let subscription = eventsService.getEventNotification().subscribe(eventTitle => 
          {
            if (eventTitle=="CHILD2_BUTTON_CLICK" ) {
               setChild2EventFired(true)
            }else{
                setChild2EventFired(false)
             }
        });
      return ()=>{
       subscription.unsubscribe();
     }
    },[])

    return <div>
         <button> {child2EventFired? 'child2 button event fired':'event not fired yet'} </button>
    </div> 
}

您的Child 2组件中的

import { eventsService} from '../services';
const Child2 =()=>{
    Child2Click=(e)=>{
        //some code, 
        //then send messages to the observable observable
        eventsService.sendEvent('CHILD2_BUTTON_CLICK');
    }

    return <div>
         <button onClick={Child2Click} >click me</button>
    </div> 
}