React主组件/首页如何响应状态变更并实现页面跳转?
React新手问题:添加数组元素并跳转首页
问题描述
我是React新手,正在Udemy课程学习基础知识,目前遇到两个无法解决的问题:
- 尝试向现有数组添加新元素时出现错误(目前手动设置id值为3)
- 状态变更后无法跳转到首页(对应
Route path="/"路径)
现有代码
Main.js
import React, { Component } from 'react'; import Title from './Title'; import Photowall from './Photowall'; import { Route, Routes } from 'react-router-dom'; import Newphoto from './Newphoto'; class Main extends Component { constructor(){ super() this.state ={ posts : [{ id: "0", description: "beautiful landscape", imageLink: "https://image.jimcdn.com/app/cms/image/transf/none/path/sa6549607c78f5c11/image/i4eeacaa2dbf12d6d/version/1490299332/most-beautiful-landscapes-in-europe-lofoten-european-best-destinations-copyright-iakov-kalinin.jpg" + "3919321_1443393332_n.jpg" }, { id: "1", description: "Aliens???", imageLink: "https://s3.india.com/wp-content/uploads/2017/12/rocket.jpg" }, { id: "2", description: "On a vacation!", imageLink: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2017/08/24/104670887-VacationExplainsTHUMBWEB.1910x1000.jpg" }] } this.handleSubmit=this.handleSubmit.bind(this) } handleSubmit = (event) => { event.preventDefault() console.log('new photo added') const newlink = event.target.elements.link.value const newdesc = event.target.elements.description.value const newpost = [{id 3: , description : newdesc, imageLink : newlink}] console.log(newpost) console.log(this.state.posts) this.setState({posts : this.state.posts.concat(newpost)}, () => {console.log(this.state.posts)}) } render() { return ( <Routes> <Route path= "/" element = { <div> <Title title={'My Gallery'}> </Title> <Photowall posts = {this.state.posts} onDelete = {this.handleDelete}> </Photowall> </div>}> </Route> <Route path= "/addanewphoto" element={ <div> <Newphoto submit = {this.handleSubmit} ></Newphoto> </div> }> </Route> </Routes> ) } } export default Main;
Newphoto.js
import React, { Component } from 'react'; class Newphoto extends Component { render() { return ( <div className='form'> <div className='form'> <form onSubmit={this.props.submit}> <input type='text' placeholder='Link' name= 'link'></input> <input type ='text' placeholder='Description' name='description'></input> <button > Post </button> </form> </div> </div> ); } } export default Newphoto;
解决方案
1. 修复数组元素添加错误
你的newpost对象存在语法错误,同时可以优化id生成逻辑:
- 修正对象语法:把
id 3:改成id: "3",规范键值对写法 - 自动生成id:基于现有posts的最大id加1,避免手动写死导致的冲突
- 可直接将单个对象传给
concat,无需额外包裹数组
2. 实现状态更新后跳转首页
由于使用的是react-router-dom v6类组件,需要借助withRouter高阶组件获取导航方法:
- 导入
withRouter - 在
setState的回调函数中调用this.props.navigate('/')完成跳转
修改后的Main.js完整代码
import React, { Component } from 'react'; import Title from './Title'; import Photowall from './Photowall'; import { Route, Routes, withRouter } from 'react-router-dom'; import Newphoto from './Newphoto'; class Main extends Component { constructor(){ super() this.state ={ posts : [{ id: "0", description: "beautiful landscape", imageLink: "https://image.jimcdn.com/app/cms/image/transf/none/path/sa6549607c78f5c11/image/i4eeacaa2dbf12d6d/version/1490299332/most-beautiful-landscapes-in-europe-lofoten-european-best-destinations-copyright-iakov-kalinin.jpg" + "3919321_1443393332_n.jpg" }, { id: "1", description: "Aliens???", imageLink: "https://s3.india.com/wp-content/uploads/2017/12/rocket.jpg" }, { id: "2", description: "On a vacation!", imageLink: "https://fm.cnbc.com/applications/cnbc.com/resources/img/editorial/2017/08/24/104670887-VacationExplainsTHUMBWEB.1910x1000.jpg" }] } this.handleSubmit=this.handleSubmit.bind(this) } handleSubmit = (event) => { event.preventDefault() const newlink = event.target.elements.link.value const newdesc = event.target.elements.description.value // 自动生成不重复的新id const maxId = Math.max(...this.state.posts.map(post => Number(post.id))) const newId = String(maxId + 1) // 修正后的新post对象 const newpost = { id: newId, description: newdesc, imageLink: newlink } this.setState( { posts: this.state.posts.concat(newpost) }, // 状态更新完成后跳转首页 () => { console.log(this.state.posts) this.props.navigate('/') } ) } render() { return ( <Routes> <Route path= "/" element = { <div> <Title title={'My Gallery'}> </Title> <Photowall posts = {this.state.posts} onDelete = {this.handleDelete}> </Photowall> </div>}> </Route> <Route path= "/addanewphoto" element={ <div> <Newphoto submit = {this.handleSubmit} ></Newphoto> </div> }> </Route> </Routes> ) } } // 用withRouter包裹组件,获取导航能力 export default withRouter(Main);
说明
- 修正后的代码解决了语法错误,能正确将新元素添加到数组
- 通过
withRouter获取导航方法,确保状态更新完成后才执行跳转 - 自动生成id的方式更健壮,避免手动设置id带来的冲突问题
内容的提问来源于stack exchange,提问作者Aparna
相关产品推荐
相关产品推荐

