私はReactの学習に取り組んでおり、それが私の組織のニーズに合っているかどうかを確認しています。私はそれがどのように機能するかを見るために取り組んできたサンプルアプリを持っています。私はここでいくつかの答えを調べましたが、私の問題を解決するものは見つかりませんでした。
「const {match:{params}} = this.props;」の「componentDidMount()」で「Uncaught(in promise)TypeError:Cannot read property'params'ofundefined」という問題が発生しています。 「」以下のコンポーネントのメソッド。同じメソッドを使用して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>
);
}
}
作業を実装する方法を示すための小さなアプリを作成しましたreact router v4
。
そこにパラメータが表示されていることがわかるように、各ルートには小道具のダンプがあります。
あなたのコードでは、なぜあなたがSwitch
fromを使用していないのかわかりませんreact-router v4
。また、あなたのルートにはexact
フラグ/プロパティがありません。このようにして、コンポーネントビューを次々にレンダリングすることはありません。
サンドボックスへのリンク:https://codesandbox.io/s/5y9310y0zn
withRouter
Appコンポーネントをラップアラウンドすることをお勧めします。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
初期状態のようなものを追加します。フェッチが終了するか、フェッチを開始するたびに、isLoading状態を切り替えます。
this.setState({ isLoading: true }); // or false
// Initial state or implement in constructor
state = { isLoading: true };
Renderメソッドは、何かをロードするたびにロードを表示し、renderComments()
コメントを返します。クリーンで読みやすいコードを取得します。
render() {
if (isLoading) {
return <div>Loading...</div>
}
return (
<div>
{this.renderComments()}
</div>
);
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加