使用usestate() 定义的变量是全局可用的
1.问题来源
普通的组件
<Input
style={style}
value={item.itemSpuTitle}
onChange={(e) => reSetRightList({ itemSpuTitle: e.target.value }, index)}
/>
编辑器组件
<Weditor
height={300}
id={‘weditor’ + index}
value={item.desc}
onChange={(desc) => {
reSetRightList({ desc }, index);
}}
/>
// 设置 reset
1.1. 出现问题
const reSetRightList=(obj,index)=>{
rightList[index] = { …rightList[index], …obj };
return […rightList];
}
1.2. 解决办法
const reSetRightList =useCallback((obj,index)=> {
return setRightList(rightList => {
rightList[index] = { …rightList[index], …obj };
return […rightList];
});
},[])
// 最终问题突破
const [list, setList]: any = useState([]);
console.log(list, ‘list1’);
// 初始化拖拽
const initSortAble = () => {
let el = document.getElementById('drap-shop');
// let $state = this.state;
new Sortable(el, {
animation: 150,
ghostClass: ‘blue-background-class’,
onEnd: (/*Event/evt) => {
const { newIndex, oldIndex } = evt;
//const {list } = $state
//console.log(list, ‘list2’);
setList((list) => {
if (oldIndex < newIndex) { // 向右移
list.splice(newIndex + 1, 0, list[oldIndex]); // 在移动到的位置插入一个元素 ##不要提到判断前##
list.splice(oldIndex, 1); // 在旧的位置删除原先的元素
} else if (oldIndex > newIndex) { // 向左移
list.splice(newIndex, 0, list[oldIndex]); // 在移动到的位置插入一个元素
list.splice(oldIndex + 1, 1); // 在旧的位置 + 1 的序列删除原先的元素
} else { // 不发生移动
return list;
}
setList([...list]);
})
},
})
}
官网api
2.扩展api
2.1 useLayoutEffect
好像没有使用虚拟dom 一样,只要是在这个方法中执行的事件能影响到 页面渲染的,都一律阻止渲染,方法全部执行完毕,才去挂载到真实的dom 上
https://www.jianshu.com/p/412c874c5add
2.2 useEffect(()=>{
prop,state
(){
…
}
})
useEffect(()=>{
api
},[])
useEffect(()=>{
(){
}
},[props])
2.3 useContext
{ba:
co:}
const ThemeContext = React.createContext(themes.light);
<ThemeContext.Provider value={themes.dark}>
</ThemeContext.Provider>
const theme = useContext(ThemeContext); return ( <button style={{ background: theme.background, color: theme.foreground }}> I am styled by theme context! );
2.4 useReducer . useState 的升级版,主要用于,多个state 之间相互依赖传值,使用useReducer
const initialState = {count: 0};
function reducer(state, action) {
switch (action.type) {
case ‘increment’:
return {count: state.count + 1};
case ‘decrement’:
return {count: state.count - 1};
default:
throw new Error();
}
}
const [state, dispatch] = useReducer(reducer, initialState);
const [state, dispatch] = useReducer(reducer, initialState,init);
2.5 useMemo 和useCallBack的作用是 shouldComponentUpdate,这个生命周期的作用,一个是返回一个数字,一个是返回一个函数
useMemo(()=>{
…
},[param])
返回一个值
export default function WithMemo() {
const [count, setCount] = useState(1);
const [val, setValue] = useState(’’);
const expensive = useMemo(() => {
console.log(‘compute’);
let sum = 0;
for (let i = 0; i < count * 100; i++) {
sum += i;
}
return sum;
}, [count]);
const expensive = () => {
console.log(‘compute’);
let sum = 0;
for (let i = 0; i < 10000; i++) {
sum += i;
}
return sum;
}
return <div>
<h4>{count}-{expensive()}</h4>
{val}
<div>
<button onClick={() => setCount(count + 1)}>+c1</button>
<input value={val} onChange={event => setValue(event.target.value)}/>
</div>
</div>;
2.6 fnb= useCallback(fna,[param])
const [num, setNum] = useState([1, 2, 3]);
const [num1, setNum1] = useState([4, 5, 6]);
const mCallback = useCallback(
() => {
console.log('callback function');
return [...num, ...num1]
}, [num]);
// const mCallback = () => {
// console.log('callback function');
// return [...num, ...num1]
// };
// useEffect(() => {
// mCallback()
// }, [num])
const ChildrenApp = ({ num, num1, callback }) => {
set.add(callback);
console.log(set);
return (
{num} - {num1} - {callback()}
)
};
const renderApp = () => {
return (
<>
<Button onClick={() => setNum([‘q’, ‘w’, ‘e’])} >change num
<Button onClick={() => setNum1([‘a’, ‘b’, ‘c’])} >change num1
</>
)
}
2.7 useRef ();
除了能定义一个组件的dom ,获取到真实的dom 元素,还能保存一个值,触发的时候不会导致浏览器渲染。其实就像是state 中一个不被使用的值一样,只不过更新state ,会导致渲染,他不会