Javascript 使用ES6将函数传递给React中的多个子组件
我有一个Javascript 使用ES6将函数传递给React中的多个子组件,javascript,reactjs,meteor,ecmascript-6,flow-router,Javascript,Reactjs,Meteor,Ecmascript 6,Flow Router,我有一个LayoutComponent,PageComponent和SingleComponent 当我的用户单击一个按钮时,我想在NewPageComponent上向用户显示一条消息,我的应用程序使用Meteor的FlowRouter路由到该消息 为此,我将消息存储在LayoutComponent的状态中,然后通过PageComponent将此消息和handlerMethod作为道具向下传递给SingleComponent,这是一个无状态功能组件 我没有运气将handler方法正确地传递到Si
LayoutComponent
,PageComponent
和SingleComponent
当我的用户单击一个按钮时,我想在NewPageComponent
上向用户显示一条消息,我的应用程序使用Meteor的FlowRouter
路由到该消息
为此,我将消息存储在LayoutComponent
的状态中,然后通过PageComponent
将此消息和handlerMethod
作为道具向下传递给SingleComponent
,这是一个无状态功能组件
我没有运气将handler方法
正确地传递到SingleComponent
,以便在LayoutComponent
上设置消息状态
我知道这是一个简单的语法问题,但有人能帮我找到我的错误吗
布局组件:
export default class LayoutComponent extends Component {
constructor() {
super();
this.state = {
message: null
};
this.handlerMethod = this.handlerMethod.bind(this);
}
handlerMethod(message) {
this.setState({ message: message });
}
render() {
// the PageComponent is actually passed via FlowRouter in this.props.content, so it needs to be cloned to add props
let contentWithProps = React.cloneElement(this.props.content, { message: this.state.message, handlerMethod: ((message) => this.handlerMethod) });
return (
<div>{contentWithProps}</div>
);
}
}
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={(message) => handlerMethod} />
</ div>
);
}
export default class SingleComponent extends Component {
constructor() {
super();
this.state = {
};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick(event) {
event.preventDefault();
// do some more stuff...
this.props.handlerMethod("You pressed the button!");
FlowRouter.go("newPage");
}
render() {
<div>
<button onClick={this.handleButtonClick}>button</button>
</div>
}
}
导出默认类LayoutComponent扩展组件{
构造函数(){
超级();
此.state={
消息:空
};
this.handlerMethod=this.handlerMethod.bind(this);
}
handlerMethod(消息){
this.setState({message:message});
}
render(){
//PageComponent实际上是通过this.props.content中的FlowRouter传递的,因此需要对其进行克隆以添加props
让contentWithProps=React.cloneElement(this.props.content,{message:this.state.message,handlerMethod:((message)=>this.handlerMethod)});
返回(
{contentWithProps}
);
}
}
页面组件:
export default class LayoutComponent extends Component {
constructor() {
super();
this.state = {
message: null
};
this.handlerMethod = this.handlerMethod.bind(this);
}
handlerMethod(message) {
this.setState({ message: message });
}
render() {
// the PageComponent is actually passed via FlowRouter in this.props.content, so it needs to be cloned to add props
let contentWithProps = React.cloneElement(this.props.content, { message: this.state.message, handlerMethod: ((message) => this.handlerMethod) });
return (
<div>{contentWithProps}</div>
);
}
}
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={(message) => handlerMethod} />
</ div>
);
}
export default class SingleComponent extends Component {
constructor() {
super();
this.state = {
};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick(event) {
event.preventDefault();
// do some more stuff...
this.props.handlerMethod("You pressed the button!");
FlowRouter.go("newPage");
}
render() {
<div>
<button onClick={this.handleButtonClick}>button</button>
</div>
}
}
constpagecomponent=({message,handlerMethod})=>{
返回(
handlerMethod}/>
);
}
组成部分:
export default class LayoutComponent extends Component {
constructor() {
super();
this.state = {
message: null
};
this.handlerMethod = this.handlerMethod.bind(this);
}
handlerMethod(message) {
this.setState({ message: message });
}
render() {
// the PageComponent is actually passed via FlowRouter in this.props.content, so it needs to be cloned to add props
let contentWithProps = React.cloneElement(this.props.content, { message: this.state.message, handlerMethod: ((message) => this.handlerMethod) });
return (
<div>{contentWithProps}</div>
);
}
}
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={(message) => handlerMethod} />
</ div>
);
}
export default class SingleComponent extends Component {
constructor() {
super();
this.state = {
};
this.handleButtonClick = this.handleButtonClick.bind(this);
}
handleButtonClick(event) {
event.preventDefault();
// do some more stuff...
this.props.handlerMethod("You pressed the button!");
FlowRouter.go("newPage");
}
render() {
<div>
<button onClick={this.handleButtonClick}>button</button>
</div>
}
}
导出默认类SingleComponent扩展组件{
构造函数(){
超级();
此.state={
};
this.handleButtonClick=this.handleButtonClick.bind(this);
}
把手按钮点击(事件){
event.preventDefault();
//多做点事。。。
这个.props.handler方法(“你按下了按钮!”);
FlowRouter.go(“新页面”);
}
render(){
按钮
}
}
您在发布的代码中没有实际调用您的handlerMethod
。因此:
handlerMethod: ((message) => this.handlerMethod)
应为:
handlerMethod: ((message) => this.handlerMethod(message))
或者更简单地说:
handlerMethod: this.handlerMethod
您的错误是传递的函数将返回this.handlerMethod而不是调用它:
handlerMethod: ((message) => this.handlerMethod) // this returns the handlerMethod function, doesn't call it
应该是
handlerMethod: ((message) => this.handlerMethod(message))
您也可以直接传递它:
handlerMethod: this.handlerMethod
直接传递它的原因是因为您正在为LayoutComponent
的构造函数内部绑定handlerMethod
的上下文,这意味着此内部handlerMethod
将固定为LayoutComponent
(请参见下面的注释)
下面是一个简短的例子:
布局组件
export default class LayoutComponent extends Component {
constructor() {
// ...
this.handlerMethod = this.handlerMethod.bind(this); // handler is bound
}
handlerMethod(message) {
// ...
}
render() {
let contentWithProps = React.cloneElement(
this.props.content, {
message: this.state.message,
handlerMethod: this.handlerMethod // pass the handler directly
}
);
return <div>{contentWithProps}</div>;
}
}
// pass the handlerMethod directly
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={handlerMethod} />
</ div>
);
}
export default class SingleComponent extends Component {
// ...
handleButtonClick(event) {
// ...
this.props.handlerMethod("You pressed the button!"); // call the passed method here
// ...
}
// ...
}
注意:从技术上讲,您可以通过调用new this.handlerMethod
来覆盖绑定的this
,但这不会发生,所以您很好。如果您只想向下传递该方法,请按以下方式执行:
const PageComponent = ({ message, handlerMethod }) => {
return (
<div>
<SingleComponent message={message} handlerMethod={handlerMethod} />
</ div>
);
}
constpagecomponent=({message,handlerMethod})=>{
返回(
);
}