我一直在努力学习React以确定它是否适合我的组织需求,所以不用说我是新手。我有一个示例应用程序,我一直在努力查看它是如何工作的。我已经在这里找到了几个答案,并且没有找到解决我问题的答案。
我遇到了问题,我得到了一个" Uncaught(承诺)TypeError:无法读取属性' params'未定义"在" componentDidMount()" at" const {match:{params}} = this.props;"下面组件中的方法。我有一个非常相似的组件,使用相同的方法从URL中获取id,并且它工作正常。我很困惑为什么一个人在工作而另一个人没有工作。我可能只是在某个地方犯了一个新手的错误(也许不止一个),任何提示/答案都会受到赞赏。
路由:
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>
);
}
}
工作组件:
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");
}
}
那个没有工作的人:
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>
);
}
}
答案 0 :(得分:2)
我已经为您创建了一个小应用,以演示如何实现工作react router v4
。
在每条路线上都有一堆道具,你可以看到那里的参数可以看到。
在您的代码中,我不明白为什么您没有使用Switch
中的react-router v4
,您的路线也没有exact
旗帜/道具。这样,您就不会一个接一个地渲染组件视图。
指向沙箱的链接:https://codesandbox.io/s/5y9310y0zn
请注意,建议在App组件周围包裹withRouter
,App组件不应包含<BrowserRouter>
。
查看代码
请注意,更新状态会触发组件的新渲染。
不要使用此处不需要的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();
在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>
)
};
在初始状态中添加isLoading
之类的内容。每次完成提取或开始提取时,都会切换为加载状态。
this.setState({ isLoading: true }); // or false
// Initial state or implement in constructor
state = { isLoading: true };
渲染方法将向我们显示每次加载内容时加载,renderComments()
将返回我们的评论。我们得到干净可读的代码。
render() {
if (isLoading) {
return <div>Loading...</div>
}
return (
<div>
{this.renderComments()}
</div>
);
}