React 使用记录分享
1、React 的 JSX 中如何使用本地静态图片资源
按照一般情况我们都会这个样子写:
<img src="./assets/images/a.png" />
但是这样在 React 里面不会生效,可以尝试以下方法:
使用 require
<img src={require('./assets/images/a.png')} />
使用 import
import imgURL from './assets/images/a.png';
<img src={ imgURL } />
2、React 单页面使用懒加载
在 React 16.6.X 过后,提供了 lazy 方法和 Suspense 组件来实现代码拆分,使用方法如下:
首先引入组件:
import React from 'react';
// 懒加载
const UserCenter = React.lazy(() => import('./components/user/UserCenter.js'));
const UserSet = React.lazy(() => import('./components/user/UserSet.js'));
在 Route 组件外使用 Suspense 组件把它包裹起,不使用 Suspense 会报错:
<React.Suspense fallback={ <div><Spin size="large" /></div> }>
<Route path="/usercenter" component={ UserCenter }></Route>
<Route path="/userset" component={ UserSet }></Route>
</React.Suspense>
fallback 这个方法主要是在组件加载完毕前做点什么,这儿我用了一个加载中的图标。这样就完成了懒加载!
3、异步请求过来的数据的渲染方式
当异步请求的数据还未赋值给需要渲染的变量是,直接渲染会报 undefined 的错误,比如下面这种:
// 初始化数据
constructor(props) {
super(props);
this.state = {
articleList: [], // 文章列表
applicationList: [], // 应用列表
projectList: [], // 项目列表
};
}
// render 函数中渲染:
<p className="detail-title">{ item.title }</p>
<div className="detail-tags-box">
<Tag>{ item.tags[0] }</Tag>
<Tag>{ item.tags[1] }</Tag>
<Tag>{ item.tags[2] }</Tag>
</div>
这样写的话,因为异步数据还未获取到,这个时候数组还是空数组,渲染时肯定会报错,所以必须加一个条件来渲染,像这样操作:
constructor(props) {
super(props);
this.state = {
loaded: false, // 异步加载数据是否已完成
articleList: [], // 文章列表
applicationList: [], // 应用列表
projectList: [], // 项目列表
};
}
定义一个变量 lodaed 来判断是否加载完毕:
api.msg.getUserInfo().then((res) => {
console.log(res.data);
this.setState({
loaded: true, // 加载完毕
articleList: res.data.articleList,
applicationList: res.data.applicationList,
projectList: res.data.projectList
})
}).catch((err) => {
console.log(err);
});
渲染函数里面这样写:
this.state.loaded && this.state.articleList.map((item, index) => {
return (
<div key={ index } className="item-detail">
<p className="detail-title">{ item.title }</p>
<div className="detail-tags-box">
<Tag>{ item.tags[0] }</Tag>
<Tag>{ item.tags[1] }</Tag>
<Tag>{ item.tags[2] }</Tag>
</div>)
})
这样以来就不会报错了。
4、Warning: Cannot update during an existing state transition (such as within render
). Render methods should be a pure function of props and state.
出现上面的这种报错,我先贴出我这儿会报错的代码
handleDelete = (index) => {
const action = {
type: 'deleteItem',
index,
};
store.dispatch(action);
}
// dom
<List dataSource={ this.state.list }
bordered
renderItem={(item, idx) => {
return (
<List.Item
actions={[<Button onClick={ this.handleDelete(idx) } type="danger">删除</Button>]}
>
{idx + 1}、{ item }
</List.Item>
)
}}
>
</List>
我上面这样调用了 this.handleDelete(idx),就报错了,那么解决方法是:
handleDelete = (index) => () => {
const action = {
type: 'deleteItem',
index,
};
store.dispatch(action);
}
像上面这样声明就不会报错了。
当报这类错误时,说明你的 props 和 states 在渲染的时候更改了。
为什么我上面像开始报错那样写会在 render 时就触发 handleDelete 执行呢,我的理解是 this.handleDelete(idx),后面的括号相当于是调用运算符,不是简单的括号。并且我的代码里面有改变 state 的操作,所以就出现那种报错了。这儿有好几种解决方法,比如:
<!-- 把 index 保存在 data-index 上,然后在事件处理函数中通过 dataset 来获取 index -->
<Button onClick={this.remove} data-index={index}>remove</Button>
remove(event){
const index = event.currentTarget.dataset.index
const temp = this.state.list;
temp.splice(index,1);
this.setState({
list:temp
})
}
或者
handleDelete(index) {
const action = {
type: 'deleteItem',
index,
};
store.dispatch(action);
}
// DOM
<List dataSource={ this.state.list }
bordered
renderItem={(item, idx) => {
return (
<List.Item
actions={[<Button onClick={ this.handleDelete.bind(this, idx) } type="danger">删除</Button>]}
>
{idx + 1}、{ item }
</List.Item>
)
}}
>
</List>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论