简体   繁体   English

使用react-router-dom 4进行反应-无法读取未定义的属性“ params”

[英]React with react-router-dom 4 — Cannot read property 'params' of undefined

I've been working on learning React to see if it suits my organization's needs, so needless to say I'm new at it. 我一直在学习React,以了解它是否适​​合我组织的需求,所以不用说我是新手。 I've got a sample app that I've been working on to see how it works. 我正在开发一个示例应用程序,以了解其工作原理。 I've gone through several of the answers here and haven't found one that fixes my problem. 我在这里经历了几个答案,但没有找到能解决我问题的答案。

I'm running into the problem where I get a "Uncaught (in promise) TypeError: Cannot read property 'params' of undefined" in the "componentDidMount()" at "const { match: { params } } = this.props;" 我遇到了一个问题,在“ const {match:{params}} = this.props”中,出现“ Uncaught(承诺)TypeError:无法读取“ componentDidMount()”中未定义的属性“ params”)。 ” method in the component below. 方法在下面的组件中。 I have a very similar component that takes an id from the url, using the same method, and it works fine. 我有一个非常相似的组件,它使用相同的方法从网址中获取ID,并且工作正常。 I'm confused as to why one is working and another isn't. 我对为什么一个有效而另一个无效的感到困惑。 I'm probably just making a rookie mistake somewhere (perhaps more than one), any hints/answers are appreciated. 我可能只是在某个地方犯了一个菜鸟错误(也许不止一个),任何提示/答案都值得赞赏。

The routing: 路由:

class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div>
          <Route path='/' component={BaseView} />
          <Route path='/test' component={NameForm} />
          <Route path='/home' component={Home} />
          <Route path='/quizzes' component={ViewQuizzes} />
          <Route path='/comment/:rank' component={GetCommentsId}  /*The one that works*//>
          <Route path='/comment/edit/:testid' component={GetCommentEdit} /*The one I'm having trouble with*//> 
          <Route path='/comments' component={GetCommentsAll} />
        </div>
      </BrowserRouter>
    );
  }
}

The working component: 工作组件:

class GetCommentsId extends Component{

  constructor (props) {
    super(props)
    this.state = {
      Comments: [],
      output: "",
      wasClicked: false,
      currentComment: " ",
    }

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

  componentDidMount(){
    const { match: { params } } = this.props;
    const url = 'http://localhost:51295/api/Values/' + params.rank;

    axios.get(url).then(res => {
      const comments = res.data;
      this.setState({ comments });      
      this.output = (
        <div>
          <ul>
            { this.state.comments.map
            (
              comment => 
              (<Comment 
                QuizId = {comment.Rank} 
                FirstName = {comment.FirstName} 
                Comments = {comment.Comments}
                TestId = {comment.TestimonialId}
              />)
            )} 
          </ul>
        </div>
      );
      //console.log("From did mount: " + this.currentComment);
      this.forceUpdate();
    });
  }

  componentDidUpdate(){}

  handleCommentChange(event){
    //console.log("handle Comment Change activated");
  }

  handleClick(comment){
    this.wasClicked = true;
    this.currentComment = comment.Comments;
    console.log(comment.Comments);
    this.forceUpdate();
  }

  render () {
    if(this.output != null){
      if(!this.wasClicked){
        return (this.output);
      }
      else{
        console.log("this is the current comment: " + this.currentComment);
        return(
          <div>
            {this.output}
            <NameForm value={this.currentComment}/>
          </div>
        );
      }
    }
    return ("loading");
  }
}

The one that isn't working: 一个不起作用的:

class GetCommentEdit extends Component {
  constructor (props) {
    super(props)
    this.state = {
      Comments: [],
      output: "",
      match: props.match
    }
  }

  componentDidMount(){
    const { match: { params } } = this.props;
    const url = 'http://localhost:51295/api/Values/' + params.testid;

    axios.get(url).then(res => {
      const comments = res.data;
      this.setState({ comments });      
      this.output = (
        <div>
          <ul>
            { this.state.comments.map
            (comment => 
              (<EditComment 
                QuizId = {comment.Rank} 
                FirstName = {comment.FirstName} 
                Comments = {comment.Comments}
                TestId = {comment.TestimonialId}
              />)
            )} 
          </ul>
        </div>
      );
      //console.log("From did mount: " + this.currentComment);
      this.forceUpdate();
    });
  }

  render(){
    return(
      <div>
        {this.output}
      </div>
    );
  }
}

I've created a small app for you to demonstrate how to implement working react router v4 . 我为您创建了一个小应用程序,以演示如何实现工作的react router v4

On each route there is a dump of props, as you can see the params are visible there. 在每条路线上都有一堆道具,正如您所看到的,在这里可以看到参数。

In your code I don't see why you are not using Switch from react-router v4 , also your routes don't have exact flag/prop. 在您的代码中,我看不到为什么不使用来自react-router v4 Switch ,而且您的路由也没有exact标记/属性。 This way you will not render your component views one after another. 这样,您就不会一个接一个地渲染组件视图。

Link to sandbox: https://codesandbox.io/s/5y9310y0zn 链接到沙箱: https : //codesandbox.io/s/5y9310y0zn

Please note that it is recommended to wrap withRouter around App component, App component should not contain <BrowserRouter> . 请注意,建议使用withRouter包裹App组件,App组件不应包含<BrowserRouter>

Reviewing your code 查看您的代码

Please note that updating state triggers new render of your component. 请注意,更新状态会触发组件的新渲染。

Instead of using this.forceUpdate() which is not needed here, update your state with values you get from resolving the Promise/axios request. 不用使用this.forceUpdate() ,而是使用解决Promise / axios请求获得的值更新状态。

  // Bad implementation of componentDidMount
  // Just remove it
  this.output = (
    <div>
      <ul>
        {this.state.comments.map
          (
          comment =>
            (<Comment
              QuizId={comment.Rank}
              FirstName={comment.FirstName}
              Comments={comment.Comments}
              TestId={comment.TestimonialId}
            />)
          )}
      </ul>
    </div>
  );
  //console.log("From did mount: " + this.currentComment);
  this.forceUpdate();

Move loop function inside render method or any other helper method, here is code for using helper method. 在render方法或任何其他辅助方法中移动循环功能,这是使用辅助方法的代码。

renderComments() {
  const { comments } = this.state;

  // Just check if we have any comments
  // Return message or just return null
  if (!comments.length) return <div>No comments</div>;

  // Move li inside loop
  return (
    <ul>
      {comments.map(comment => (
        <li key={comment.id}>
          <Comment yourProps={'yourProps'} />
        </li>
      ))}
    </ul>
  )
};

Add something like isLoading in your initial state. 在初始状态下添加类似isLoading Toggle isLoading state each time you are done with fetching or you begin to fetch. 每次完成获取或开始获取时,切换isLoading状态。

this.setState({ isLoading: true }); // or false

// Initial state or implement in constructor
state = { isLoading: true };

Render method will show us loading each time we are loading something, renderComments() will return us comments. Render方法将在每次加载某些东西时显示给我们加载, renderComments()将返回我们的注释。 We get clean and readable code. 我们获得干净易读的代码。

render() {
  if (isLoading) {
    return <div>Loading...</div>
  }

  return (
    <div>
      {this.renderComments()}
    </div>
  );
}

暂无
暂无

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

相关问题 Reactjs:React-router-dom 无法读取未定义的属性推送 - Reactjs: React-router-dom Cannot Read Property Push of Undefined 给我的反应路由器无法读取未定义的位置属性。 (反应路由器 dom 版本 5.2.0) - React router giving me cannot read property of location undefined. (react-router-dom version 5.2.0) 未捕获的类型错误:使用 axios 和 react-router-dom 时无法读取未定义的属性(读取“参数”) - Uncaught TypeError: Cannot read properties of undefined (reading 'params') while using axios and react-router-dom TypeError:无法读取 react^16.13.1 react-router-dom^5.2.0 中未定义的属性“位置” - TypeError: Cannot read property 'location' of undefined in react^16.13.1 react-router-dom^5.2.0 未捕获的类型错误:无法读取未定义的属性“推送”(React-Router-Dom) - Uncaught TypeError: Cannot read property 'push' of undefined (React-Router-Dom) 为什么我会收到 TypeError:无法读取未定义的 react-router-dom 的属性“push” - Why am I getting TypeError: Cannot read property 'push' of undefined react-router-dom 无法读取未定义的属性(读取“搜索”)。 我的位置返回未定义,这是 react-router-dom v6 - Cannot read properties of undefined (reading 'search'). My location returning undefined and this is react-router-dom v6 TypeError:无法在 App React 路由器上读取未定义的属性“参数” - TypeError: Cannot read property 'params' of undefined at App React Router &#39;TypeError: 使用&#39;react-router-dom&#39; 的&#39;useHistory&#39; 钩子时无法读取未定义的属性(读取&#39;push&#39;)&#39; - 'TypeError: Cannot read properties of undefined (reading 'push')' when using 'useHistory' hook of 'react-router-dom' 使用 react-router-dom 未定义道具 - Props is undefined using react-router-dom
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM