React Link onClick setState返回未定义

时间:2019-08-15 11:32:26

标签: reactjs

我有一个带有按钮的组件,因为我需要滚动到网页上的特定位置并设置组件状态,所以我将其更改为Link组件。

该函数在使用button组件时起作用,并且console.log记录所需的值。但是,将button更改为Link时,返回的值为undefined

组件:

import React, { Component } from "react";
import { Link } from "react-scroll";

class Scroll extends Component {
  constructor(props) {
    super(props);
    this.state = {
      value: ""
    };

    this.setValue = this.setValue.bind(this);
  }

  setValue = e => {
    this.setState({ value: e.target.value });
    console.log(this.state.value);
  };

  render() {
    return (
      <div>
        <Link
          value="feature"
          onClick={this.setValue}
          className="action-button"
          to="signup-wrapper"
          activeClass="active"
          spy={true}
          smooth={true}
          offset={-100}
          duration={200}
        >
          See Feature
        </Link>
      </div>
    );
  }
}

export default Scroll;

如何使其工作,以便Link组件可以向下滚动到特定元素并成功更改状态?

2 个答案:

答案 0 :(得分:1)

<Link>组件没有值,例如按钮或输入。我猜您需要使用element.getAttribute访问value属性:

  setValue = e => {
    this.setState({ value: e.target.getAttribute('value') });
  };

此外,请记住setState是异步的,因此在之后使用console.log()将显示先前的值,而不是新的值。

答案 1 :(得分:1)

此答案要求您重构代码,因为我使用的是props而不是Link组件上的值,但是我创建了一些带有一些注释的样板代码,以便您了解发生了什么。

当我发现钩子的时候,我的生活就永远改变了。我强烈建议您从Facebook的家伙那里观看youtube(90% Cleaner React With Hooks)上的视频。

如果您复制代码并删除注释,您将看到多少清洁的纯组件而不是类和标准组件(尽管该规则有一些例外)。

希望这会有所帮助,并且很乐意回答任何问题

import React, { useState, useEffect } from "react";
import { Link } from "react-scroll";

export default function Scroll(props) {
    // No contructor!

    // This is a two pronged attack:
    //  - foo: This is the variable you want to declare
    //  - setFoo: This is the function that will update it.
    //            this saves a lot of time writing out this.setState({...})
    const [foo, setFoo] = useState("");

    // This is like an event listener, the code inside the function will be 
    // exectuted whenever the specified variables stored in [] changes -                 
    // like ComponentDidUpdate with a filter.
    useEffect(() => console.log(foo), [foo]);

    // You can leave this array empty, and it will run the code inside on mount. Useful for fetching data from an API asyncrounously.

    // Render function is not required, just return a jsx object
    return (
        <div>
            <ScrollButton value="feature" text="See Feature" setFoo={setFoo} />
            <div style={{ height: 5000 }} />
            <div className="signup-wrapper">Content to scroll to</div>
        </div>
    );
}

function ScrollButton(props) {
    return (
        <Link
            onClick={() => props.setFoo(props.value)}
            className="action-button"
            to="signup-wrapper"
            activeClass="active"
            spy={true}
            smooth={true}
            offset={-100}
            duration={200}
        >
            {props.text}
        </Link>
    );
}