我想在我的 React Native 应用程序中实现一个从父级到子级组件的事件侦听器,我正在使用 StackNavigator 作为路由器。
如何侦听顶部/父组件中发生的事件?
只需使用 React Native 的DeviceEventEmitter
即可。从父组件发出事件,如下所示:
DeviceEventEmitter.emit('eventKey', {name:'John', age:23});
和侦听子组件中的事件
componentDidMount(){
//add listener
this.eventListener = DeviceEventEmitter.addListener('eventKey',this.handleEvent);
}
handleEvent=(event)=>{
//Do something with event object
}
componentWillUnmount(){
//remove listener
this.eventListener.remove();
}
最好的方法不是以我目前的经验(7 个月后这个问题(使用 EventEmitter,而是使用 Redux 作为状态持有者,您可以创建将通过组件父子传递消息的变量,然后连接组件以获取变量(状态(更改立即发生。
我决定使用Rematch,这是Redux的缩小版本,我得到了非常好的结果。它迫使我删除所有事件发射器,并使用调度方法来更新将在连接的组件中更新的变量(状态(。
最简单的方法:
1( 在您的应用中创建侦听器.js (初始启动文件(:例:
(new NativeEventEmitter()).addListener('loggedIn',() => {
setAuth(true);
});
2(只需从任何孩子发出:(new NativeEventEmitter()).emit('loggedIn');
希望它对某人有用!
我一直在研究如何在 React Native 中将事件从父组件发出和侦听到子组件,在尝试了不同的方式之后,我认为分享我是如何让它工作的可能会很好。
在您的父组件(在我的例子中是 App.js(中,导入事件发射器库:
import EventEmitter from 'EventEmitter';
创建事件发射器的变量实例:
export default class App extends Component {
...
componentWillMount() {
this.eventEmitter = new EventEmitter();
}
...
}
然后,当发生某些事情时,发出事件:
this.eventEmitter.emit('Event-Name', {args});
由于我使用 StackNavigator 作为路由器,我必须将我的 eventEmitter 变量传递给子视图:
const routes = {
ChildView1: {
screen: ChildComponent1
},
ChildView2: {
screen: ChildComponent2
},
...
};
const AppNavigator = StackNavigator(
{
...routes,
},
{
initialRouteName: 'ChildView1',
headerMode: 'none',
/*
* Use modal on iOS because the card mode comes from the right,
* which conflicts with the drawer example gesture
*/
mode: Platform.OS === 'ios' ? 'modal' : 'card',
}
);
/* Here is the magic for the children views */
render(){
return (
<AppNavigator screenProps={this.eventEmitter} />
);
}
好的,现在我们已经为子视图提供了事件侦听器,让我们在其中一个子组件中进行调用:
export default class ChildComponent1 extends Component {
ComponentWillMount(){
this.eventEmitter = this.props.screenProps;
this.eventEmitter.addListener('Event-Name', ()=>{
// Do something
});
}
...
}
这就是我为子组件完成事件侦听器的方式,我希望它对其他人有所帮助。如果您有更好的实现,请分享/评论它。
在跟踪事件的来源或侦听的位置时,拥有事件发射器可能会变得有点混乱。
就像你通过screenProps={this.eventEmitter}
将事件发射器传递给子代一样(这就是你本质上正在做的事情(,为什么不传递一个实际函数,你的孩子可以用来启动对其父级的操作。这可能是最有反应的做事方式。
添加额外的事件侦听器可能并不理想,因为它会在某个时候影响性能。
我遵循了使用 redux 的 OP 想法,它对我来说效果很好。这是代码...
操作类型.js:
export const TRIGGER_REQUEST_SUBMIT = "TRIGGER_REQUEST_SUBMIT";
export const ACKNOWLEDGE_REQUEST_SUBMIT = "ACKNOWLEDGE_REQUEST_SUBMIT";
事件操作.js:
import * as types from "./actionTypes";
export function triggerRequestSubmit() {
return function(dispatch) {
dispatch({ type: types.TRIGGER_REQUEST_SUBMIT });
};
}
export function acknowledgeRequestSubmit() {
return function(dispatch) {
dispatch({ type: types.ACKNOWLEDGE_REQUEST_SUBMIT });
};
}
事件Reducer.js:
import * as types from "../actions/actionTypes";
import initialState from "./initialState";
export default function eventReducer(state = initialState.event, action) {
switch (action.type) {
case types.TRIGGER_REQUEST_SUBMIT:
return { ...state, shouldSubmitRequest: true };
case types.ACKNOWLEDGE_REQUEST_SUBMIT:
return { ...state, shouldSubmitRequest: false };
default:
return state;
}
}
不要忘记在您的根化简器/索引中注册化简器.js在化简器中注册化简器
初始状态.js:
export default {
event: {
shouldSubmitRequest: false
}
};
在 child 中的用法(使用 redux 连接 & 获取 shouldSubmitRequest via state, acknowledgeRequestSubmit via dispatch(:
useEffect(() => {
if (shouldSubmitRequest) {
console.log("shouldSubmitRequest triggered in Request");
acknowledgeRequestSubmit();
}
}, [shouldSubmitRequest]);
在父调用触发器请求提交((;(连接到 Redux 以获取该方法(