当父组件的某个值属性传递给子组件,子组件依赖此参数自动调用接口数据更新内部列表视图,同时依赖接口返回的数据更新echart视图,如果数据返回后同时执行两个set方法,setDataList...setOption...,会出现echart视图慢List视图一次,具体代码如下:
通过一个定时器模拟父组件元素在变化,以下为Parent.tsx组件
import React from 'react';
import Child from './child'
import Child2 from "./child-2"
import 'echarts-liquidfill';
const RcLiqudFill: React.FC = function () {
const [random, setRandom] = React.useState(-1)
React.useEffect(() => {
const timer = setInterval(() => {
setRandom(Date.now())
}, 1000)
return () => {
clearInterval(timer)
}, [])
return (
<Child random={random} />
<Child2 random={random} />
export default RcLiqudFill
child1组件
import React from 'react';
import ReactECharts from 'echarts-for-react';
import graphOption from '../data/iquidfill-data'
import { cloneDeep } from "lodash-es"
import 'echarts-liquidfill';
type IProps = {
random: number;
const RcLiqudFill: React.FC<IProps> = function (props) {
const [list, setList] = React.useState([[0]])
const [opt, setOpt] = React.useState(graphOption)
const instance = React.useRef(null)
React.useEffect(() => {
fetch('/examples/data/asset/data/life-expectancy-table.json')
.then(res => {
res.json().then(data => {
// 错误解法,同时执行两个set方法
// setList(data.map(arr => ([parseInt(Math.random().toString().slice(-2)), ...arr])))
// const newOpt = cloneDeep(graphOption)
// newOpt.series[0].data = [list[0][0]* 0.01]
// 问题:慢一个数
// instance.current.getEchartsInstance().setOption(newOpt)
// setOpt(newOpt)
// 正确解法,在setList内部执行setOpt
setList(prevState => {
const newDataList = data.map(arr => ([parseInt(Math.random().toString().slice(-2)), ...arr]))
const newOpt = cloneDeep(graphOption)
newOpt.series[0].data = [newDataList[0][0]* 0.01]
// instance.current.getEchartsInstance().setOption(newOpt)
setOpt(newOpt)
return newDataList
}, [props.random])
return (
<div style={{
width: 300,
height: 100,
overflow: 'auto',
border: '1px solid #ff0000',
whiteSpace: 'nowrap'
list.map(arr => (<div key={arr.join(',')}>{arr.join(',')}</div>))
}</div>
<ReactECharts
ref={instance}
option={opt}
style={{ width: 320, height: 300 }}
export default RcLiqudFill
child2解法,使用useMemo
import React from 'react';
import ReactECharts from 'echarts-for-react';
import graphOption from '../data/iquidfill-data'
import { cloneDeep } from "lodash-es"
import 'echarts-liquidfill';
type IProps = {
random: number;
const RcLiqudFill2: React.FC<IProps> = function (props) {
const [list, setList] = React.useState([[0]])
const instance = React.useRef(null)
const opt = React.useMemo(() => {
const newOpt = cloneDeep(graphOption)
newOpt.series[0].data = [list[0][0]* 0.01]
return newOpt
}, list)
React.useEffect(() => {
fetch('/examples/data/asset/data/life-expectancy-table.json')
.then(res => {
res.json().then(data => {
setList(data.map(arr => ([parseInt(Math.random().toString().slice(-2)), ...arr])))
}, [props.random])
return (
<div style={{
width: 300,
height: 100,
overflow: 'auto',
border: '1px solid #ff0000',
whiteSpace: 'nowrap'
list.map(arr => (<div key={arr.join(',')}>{arr.join(',')}</div>))
}</div>
<ReactECharts
ref={instance}
option={opt}
style={{ width: 320, height: 300 }}
export default RcLiqudFill2
该库假定Promise可以作为全局资源使用。
// using flux terminology for shared vocabulary, but this library does
// not have any opinion about flux
var {
RouteHandler , // <-- not the usual RouteHandler!
} = require ( 'react-router-async-props' ) ;
var Groups = React . createClass ( {
statics : {
asyncP
使用 useState() 进行状态管理
useState()是改变状态的开关,将状态添加到函数组件需要4个步骤:启用状态、初始化、读取和更新。
import React, { useState } from 'react'; //1.启用状态
const [state, setstate] = useState(initialState); //2.初始化状态
consloe.log(state); //3.读取
setstate(newState); //4.更新状态
useState()使用回调更
使用深拷贝:在更新 state 时,使用深拷贝将旧的 state 值复制给新的 state,这样一来,新的 state 值的地址与旧的 state 不同,就能够触发重新渲染了。在上述代码中,使用 JSON.parse(JSON.stringify()) 方法对旧的 state 进行深拷贝,并修改其 age 属性后作为新的 state 值,从而可以正常触发重新渲染。使用不可变数据类型:使用不可变的数据类型,如字符串、数字和布尔值,而不是引用类型的对象,这样就不会出现值被修改但地址相同的问题。
React 强制更新组件
通常组件的更新是 state 或者 props 改变造成的,有时候数据没有改变,如何强制更新组件?
如果 render() 方法依赖于其他数据,则可以调用 forceUpdate() 强制让组件重新渲染。
调用 forceUpdate() 将致使组件调用 render() 方法,此操作会跳过...
yarn 是 facebook 发明的新一代 js 包管理器,支持离线使用。这是 npm 与 yarn 的 命令对照。
但是,这种做法相当耗时。有没有更简单的方法呢? 答案是使用 npm-check 或者 yarn。两者都需要全局安装。
const [textList, setTextList] = useState(原数组);
setTextList(新数组);
当修改原数组时,如果原数组是个深层数组(不只一层),使用setTextList修改时,不会触发页面刷新
原因分析:
这个涉及到可变对象和不可变对象的知识,在vue和react中,如果更新可变对象时,可能会引起视图更新,这是因为,vue和react默认都是浅监听,只会监听数据的第一层,内层数据发生改变,并不会监听到
Background
最近项目需要用到React.js的知识,做个web tagging的功能,需要针对按钮和一些变量的变化进行触发,于是需要用到useEffect处理多个useState的解决方法。
有type和status两个变量,
如果同时触发,如果单独触发,执行不同的功能
useState定义
const [type, setType] = useState(‘支付宝’);
const [status, setStatus] = useState(‘全部’);
useEffect处理
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bHvx9zrJ-1679034311702)(/upload/2023/03/image-6b5cd80bd2364c31b6aec4ea898d6f00.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iMigiZ45-1679034311703)(/upload/2023/03/image-d6c31d9f276645618e11f7edaad0bc41.png)]
export const Test = () => {
const obj = sum(a, b); // 不只是对象,数组也会出现这种情况
const [num, setNum] = useState(0);
useEffect(()=>{
setNum(num + 1);
}, [obj])
return (
<div>{ num }</di
React是什么呢?相信每个做开发的人对它都或多或少有一些印象;这里我们来看一下官方对它的解释:用于构建用户界面的 JavaScript 库;目前对于前端开发来说,几乎很少直接使用原生的JavaScript来开发应用程序,而是选择一个JavaScript库(框架)。在过去的很长时间内,jQuery是被使用最多的JavaScript库;在过去的一份调查中显示,全球前10,000个访问最高的网站中,有65%使用了jQuery,是当时最受欢迎的JavaScript库;但是,目前甚至已经处于淘汰的边缘了;
为了更新的安全和可靠,React的状态一直都比较封闭,不论是早期类组件的this.state,还是 hook 年代的,React 依赖外部数据更新都不是很容易。要使 React 订阅外部数据,外部数据的就需要有数据更新的回调,使得更新能够通知 React。