简体   繁体   English

通过三个组件级别传递函数(即从孙组件调用函数)

[英]Passing a function through three levels of components (i.e. calling a function from a grandchild component)

I want to pass an item id from either a Child component or grandchild component, but cannot figure out how to do so. 我想从子组件或孙组件传递项ID,但无法弄清楚如何这样做。 Other examples I have looked at show using the arrow function to achieve this, but for whatever reason my function is not getting called. 我看过的其他示例使用箭头函数来实现这一点,但无论出于何种原因我的函数都没有被调用。

I have the following in Parent.js : 我在Parent.js有以下Parent.js

chosenItem(id){
    console.log("CHOSEN ITEM SELECTED")
    this.setState({
        chosen_item: id
    })
}

and in the Parent.js render function: 并在Parent.js渲染函数中:

<Child objects={objects} chosenItem={() => this.chosenItem()} />

Then in my Child.js I have: 然后在我的Child.js我有:

items = this.props.objects.items.map(item => {
    return (
        <ClickableTextComponent
            key={item.id}
            text={item.label}
            onClick={item =>this.props.chosenItem(item.id)}
         />
     )
 })

In my Child.js render function I have: 在我的Child.js渲染功能中,我有:

{items}

I also wasn't sure whether the actual click event should go inside of the Child.js or the ClickableTextComponent. 我也不确定实际的click事件是否应该进入Child.js或ClickableTextComponent。 Or does it really matter? 或者它真的重要吗? Currently I have placed it in the Child.js component as seen above. 目前我将它放在Child.js组件中,如上所示。

What am I doing wrong? 我究竟做错了什么? How can I modify my code so that the function gets called? 如何修改我的代码以便调用该函数? I have read a bit about currying to prevent a function from being recreated multiple times. 我已经阅读了一些关于currying的内容,以防止多次重新创建函数。 Is that necessary in this case? 在这种情况下,这是必要的吗? If so, where and how should I be implementing it. 如果是这样,我应该在何处以及如何实施它。 In my Parent or Child components? 在我的父母或儿童组件?

Update 更新

I was previously trying to get the onClick to work from Child.js, but as it needs to be attached to a div I have moved it to ClickableTextComponent (the grandchild component). 我以前试图让onClick从Child.js开始工作,但由于它需要附加到div我已经将它移动到ClickableTextComponent(孙子组件)。

One issue with ClickableTextComponent is that I want to be able to set the state when the component is clicked so that I can turn the component a different colour. ClickableTextComponent一个问题是我希望能够在单击组件时设置状态,以便我可以将组件转换为不同的颜色。 Because of that I am needing to use a function to then call the chosenItem function. 因此,我需要使用函数然后调用selectedItem函数。 So here is what I have in my `ClickableTextComponent.js': 所以这就是我在`ClickableTextComponent.js'中的内容:

handleClick(){
    this.setState({
        text_state: "clicked"
    })
    this.props.chosenItem()
}

In the render I then have: 在渲染中,我有:

<div
    onClick={this.handleClick.bind(this)}
    onMouseOver={this.changeTextState.bind(this, "hover")}
    onMouseOut={this.changeTextState.bind(this, "default")}
>{this.props.text}</div>

New Error 新错误

Based on the above changes, I am now getting this.props.chosenItem is not a function . 基于以上的变化,我现在得到this.props.chosenItem is not a function However, I cannot figure out why it is giving me this error. 但是,我无法弄清楚为什么它会给我这个错误。 I can see the function name when I display this.props to the console. 当我向控制台显示this.props时,我可以看到函数名称。 What am I doing wrong? 我究竟做错了什么?

The answer given by Kevin He holds true. Kevin He给出的答案是正确的。 But there is one problem with that solution. 但是该解决方案存在一个问题。

<Child objects={objects} chosenItem={(x) => this.chosenItem(x)} />

When you do such, every time your parent is rerendered. 当你这样做时,每次你的父母被重新渲染。 It will create a new instance of the function. 它将创建一个新的函数实例。 And, your child component also rerenders because It sees the props changing. 并且,您的孩子组件也会重新渲染,因为它会看到props变化。

Best solution is: 最佳解决方案是:

<Child objects={objects} chosenItem={this.chosenItem} />

Update: 更新:

Now, it seems to make sense. 现在,它似乎有道理。

The problem is again with ClickableTextComponent . 问题再次出现在ClickableTextComponent

Here is the update ClickableTextComponent which works. 这是更新的ClickableTextComponent

https://codesandbox.io/s/73x6mnr8k0 https://codesandbox.io/s/73x6mnr8k0

The main problem: 主要问题:

items = this.props.objects.items.map(item => {
    return (
        <ClickableTextComponent
            key={item.id}
            text={item.label}
            onClick={item =>this.props.chosenItem(item.id)}
         />
     )
 })

//
// Here you made a function (item) => this.props.choseItem(item.id)
// That means when you call that function you should call like this
// i.e. passing parameter needed for the function
// 

handleClick(){
    this.setState({
        text_state: "clicked"
    })
    this.props.chosenItem(item)
}

//
// But do you do not have the item in the children
// Parent should be changed as below
//

items = this.props.objects.items.map(item => {
    return (
        <ClickableTextComponent
            key={item.id}
            text={item.label}
            onClick={() =>this.props.chosenItem(item.id)}
         />
     )
 })

//
// Now you made a fuction () => this.props.chosenItem(item.id)
// The main difference being you are not taking a item as parameter
// item will be taken from outer scope that means, item from map
//

// 
// Another solution can be
// 

items = this.props.objects.items.map(item => {
    return (
        <ClickableTextComponent
            key={item.id}
            id={item.id}
            text={item.label}
            onClick={this.props.chosenItem}
         />
     )
 })

// And in ClickableTextComponent

handleClick(){
    this.setState({
        text_state: "clicked"
    })
    this.props.chosenItem(this.props.id)
}

You can do this: 你可以这样做:

<Child objects={objects} chosenItem={(x) => this.chosenItem(x)} />

Note that chosenItem is a function, then whenever it's called with item.id , it will take call the function this.chosenItem at the parent element. 请注意, chosenItem是一个函数,然后无论何时使用item.id调用它,它都会在父元素上调用函数this.chosenItem

暂无
暂无

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

相关问题 如何将祖父组件中的 function 传递给 ReactJs 中的孙子组件? - How Can I pass a function in grandparent component to grandchild components in ReactJs? React:如何在我无法控制的 function 组件中使用 refs(即来自库) - React: How to use refs in a function component that I have no control over (i.e. from a library) 三级事件监听器(从父级到孙级) - Event listener three levels (from parent to grandchild) 从孙子指令在控制器中调用父函数会导致参数未定义 - Calling parent function in controller from grandchild directive results in undefined parameter 从孙子组件内部调用祖父方法 - calling grandparent method from inside the grandchild component 在React中向孙子传递带有参数的函数时出错 - Error on passing down function with argument to grandchild in React 通过 React 功能组件将 function 从父级传递给子级 - Passing down function from parent to child through React functional component 传递 function 以通过道具将 state 从 class 组件编辑为基于 function 的组件无效 - Passing a function to edit state from class component to function based component through props not working 将动态函数从父组件传递给孙组件 Angular - Passing dynamic functions from parent component to grandchild component Angular Javascript函数就像对象,即“$”可以用作函数,例如$()以及对象$ - Javascript Function like Objects i.e. “$” can be used as a function e.g. $() as well as an object $
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM