简体   繁体   English

祖父母组件未将参数传递给函数

[英]Grandparent component doesn't pass argument to function

I have some doubts trying to understand how react works with functions as props, passing them around to child components. 我对尝试理解react如何与作为props的功能一起工作,并将它们传递给子组件感到怀疑。 I already saw some tutorials but didn't grasp my issue at the moment. 我已经看过一些教程,但目前还不了解我的问题。

Basically I have a simple component that passes a list down, and other component that handles the list with Array.map to render another component. 基本上,我有一个简单的组件可以向下传递列表,其他组件则可以使用Array.map处理该列表以呈现另一个组件。

Basically I have the following: 基本上我有以下几点:

App.js -> Quotes -> Quote. App.js->报价->报价。

And I want to handle the click on the Quote component. 我想处理对Quote组件的单击。 So everytime the user clicks Quote I want to handle it on the APP.js. 因此,每次用户单击Quote时,我都希望在APP.js上处理它。

I already tried to pass the reference as a prop down and in the app.js quotes component to call the function, but it didn't work. 我已经尝试过将引用作为道具传递下来,并在app.js引号组件中调用该函数,但这没有用。

This is what I tried till now: 这是我到目前为止尝试过的:

App.js App.js

import React, { Component } from 'react';
import classes from './App.module.css';

import Quotes from '../components/quotes/quotes'

class App extends Component {
  state = {
    quotes: [
      { id: 1, text: "Hello There 1" },
      { id: 2, text: "Hello There 2" },
      { id: 3, text: "Hello There 3" },
      { id: 4, text: "Hello There 4" }
    ],
    clickedQuote: "none"
  }

  handleClickedQuote (id) {
    console.log(id)
    const quoteIndex = this.state.quotes.findIndex(q => q.id === id)

    this.setState({
      clickedQuote: this.state.quotes[quoteIndex].text
    })
  }

  render() {
    return (
      <div className="App">
        <div className={classes['quotes-wrapper']}>
          <Quotes clicked={this.handleClickedQuote} quotes={this.state.quotes}/>
          <p>clicked quote {this.state.clickedQuote}</p>
        </div>
      </div>
    );
  }
}

export default App;

Quotes.js Quotes.js

import React from 'react';
import Quote from './quote/quote'

const quotes = (props) => props.quotes.map((quote) => {
  return (
    <Quote clicked={props.clicked} text={quote.text}/>
  )
})

export default quotes

Quote.js Quote.js

import React from 'react';
import classes from './quote.module.css'

const quote = (props) => {
  return (
    <div onClick={() => props.clicked(props.id)} className={classes.quote}>
      <p className={classes['quote-text']}>{props.text}</p>
    </div>
  )
}

export default quote

I need to get the id on the hanleClickedQuote in the App.js function. 我需要在App.js函数的hanleClickedQuote上获取ID。 What am I doing wrong? 我究竟做错了什么?

You need to explicitly pass the id as a prop. 您需要显式传递id作为道具。 So, in Quotes.js in your map() , something like: 因此,在map()中的Quotes.js中,类似:

<Quote id={quote.id} clicked={props.clicked} text={quote.text}/>

Update: as @Ashkan said in their answer, you also need to properly bind your handler. 更新:正如@Ashkan在回答中所说,您还需要正确绑定处理程序。

Well there are two things going very wrong in your code. 好了,在您的代码中有两件事是非常错误的。 First one is a common problem in JS community. 第一个是JS社区中的常见问题。 I suggest you read deeper into the usage of the 'this' keyword. 我建议您更深入地了解'this'关键字的用法。 in App.js you are defining your method as a function declaration. 在App.js中,您将方法定义为函数声明。

handleClickedQuote(id) {
    console.log(id)
    const quoteIndex = this.state.quotes.findIndex(q => q.id === id)

    this.setState({
        clickedQuote: this.state.quotes[quoteIndex].text
    })
}

Now the 'this' keyword in function declarations are dynamically set, meaning 'this' here actually gets set when the function gets called and since it's an event handler, the value of 'this' will actually be your event! 现在,函数声明中的'this'关键字是动态设置的,这意味着'this'实际上是在调用函数时设置的,并且由于它是事件处理程序,因此'this'的值实际上就是您的事件! You can test it out. 您可以测试一下。 But we want 'this' to refer to our class so we can access the state. 但是我们希望“ this”引用我们的类,以便我们可以访问状态。

There are two ways to fix this, first: 有两种解决方法,第一种:

You can bind the correct value for 'this' in the constructor of your App.js class like this (the old way): 您可以像这样(旧方法)在App.js类的构造函数中为“ this”绑定正确的值:

constructor(props) {
    super(props);
    this.handleClickedQuote = this.handleClickedQuote.bind(this);
}

This replaces the method in your class with a version that uses the correct 'this' value at the construction step of your object. 这将用您的对象构造步骤中使用正确的“ this”值的版本替换类中的方法。

Or simpler yet, you can use an arrow function since the 'this' keyword in an arrow function is set lexically: 或更简单一点,由于箭头函数中的'this'关键字是按词法设置的,因此可以使用箭头函数:

handleClickedQuote = id => {
    console.log(id);
    const quoteIndex = this.state.quotes.findIndex(q => q.id === id);

    this.setState({
        clickedQuote: this.state.quotes[quoteIndex].text
    });
}

NOTE: In an arrow function the value of 'this' basically refers to whatever is outside of that code block which in this case is your entire object. 注意:在箭头函数中,“ this”的值基本上是指该代码块之外的所有内容,在这种情况下,这是您的整个对象。

Also you have a minor mistake in your code which someone mentioned. 另外,您在代码中有一个小错误,有人提到过。 You actually forgot to pass the id of the quote as a prop to the Quote component. 您实际上忘记了将报价ID作为道具传递给Quote组件。 But that's just a minor oversight. 但这只是一个小小的疏忽。 It's important to know this problem has less to do with React than JS itself. 重要的是要知道这个问题与React的关系比JS本身少。 My advice is getting a little deeper into JS and learning all the quirks and technicalities of the language. 我的建议是对JS进行更深入的学习,并学习该语言的所有怪癖和技术知识。 It will save you a lot of hassle in the future. 它将为您节省很多麻烦。 Also work on your debugging skills so mistakes like the missing prop don't fall through the cracks so easily. 还可以利用您的调试技能,因此像丢失道具这样的错误就不会那么容易地掉入裂缝。

Best of luck 祝你好运

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

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