使用数组模拟面包屑
const str = '1/2/3/4/1.text';
const items = str.split('/').reduce((acc, curr) => {
if (!acc.length) {
return [curr];
} else {
return [...acc, `${acc[acc.length - 1]}/${curr}`];
}
}, []);
console.log(items)
// ['1', '1/2', '1/2/3', '1/2/3/4', '1/2/3/4/1.text']
useEffect为什么不能直接写async,而useCallback可以?
这是由于useEffect
在设计上决定的。useEffect
接受一个函数,这个函数返回undefined
或者一个函数(用于cleanup
)。
而如果是传给useEffect
一个async
,那么他将得到一个promise
,这与useEffect
的预期不符。useCallback
就没有cleanup
的需要,所以可以自由的使用async
。
对create-react-app项目使用addLessLoader添加less支持时的报错问题
尝试方案1
adjustStyleLoaders(({ use: [, , postcss] }) => {
const postcssOptions = postcss.options;
postcss.options = { postcssOptions };
}),
结果:无效
尝试方案2
PostCSS Loader has been initialized using an options object that does not match the API schema
const { override } = require('customize-cra');
const addLessLoader = require('customize-cra-less-loader');
module.exports = override(addLessLoader());
结果:有效
react组件传递参数的方式不同导致的bug
const timestamp = Date.now();
// 只传key
<Demo timestamp />
// Demo组件的props为
// { timestamp: true }
// 传key和value
<Demo timestamp={timestamp} />
// Demo组件的props为
// { timestamp: 1707971983365 }
上面的两种传值方式,会导致得到不同的值,当你明确的知道是需要的是boolean
值,并且为true
,你当然可以只传key
,但有时我们可能意外的将非boolean
值使用这种方式传递给组件,因此而导致bug
,所以为了避免预料之外的情况,建议始终传递key
和value
。
ps: 如果期望的是boolean
值false
,那么必须使用key
和value
的形式
<Demo value />
// Demo组件的props为
// { value: true }
<Demo value={false} />
// Demo组件的props为
// { value: false }
react-router-dom@5中的exact作用
用于是否启用精确匹配
当前url
为/one
当exact: false
,未开启精确匹配,由于前四位字符一致,所以会匹配/one/two
当exact:true
,启用精确匹配,由于/one
后面的字符不一致,所以不会匹配/one/two
如何在react@18中使用contenxt?
创建一个
context
const ThemeContext = React.createContext(null);
使用
ThemeContext.Provider
将应用包起来,并且将需要共享的数据传给给value
字段。<ThemeContext.Provider value="light"> <App /> </ThemeContext.Provider>
使用
useContext
读取被共享的数据function Demo() { const theme = useContext(ThemeContext) return <div>theme: {theme}</div> }
修改
context
的当前值
需要借助useState
,将setContext
作为数据传递给所有组件,这样就可以在任何地方修改顶层的context
,并且将更新同步给所有组件了。const [context, setContext] = useState(initialState) <ThemeContext.Provider value={{ context, setContext, }}> <App /> </ThemeContext.Provider>
注意事项
createContext
的参数是默认值,但是需要注意,这里指的并不是Provider
的value
不传时,启用createContext
的参数作为默认值。而是当组件树上没用使用Provider
包裹时,才启用这里的参数作为默认值。
const ThemeContext = React.createContext(null);
如何高亮当前路由?
import { useLocation } from 'react-router-dom';
const { pathname } = useLocation();
使用useLocation
得到当前pathname
,然后使用pathname
去与菜单对比,实现当前路由高亮
classnames的动态class如何书写?
const classes = classnames([
styles.item,
{
[styles.active]: true,
},
]);
当一个useEffect中的函数被外部需要,怎么做?
如下代码,其中loadData
在组件初始化的时候需要用到,这很常见,所以我们把它写在了一个空依赖的useEffect
中了。
useEffect(() => {
const loadData = async () => {
const res = await getData();
setItems(res.data);
};
loadData();
}, []);
下面,出现了一个新的需求,我们需要在新增数据后,重新拉取一下远程数据,以保持同步。所以,就需要再次调用loadData
,可现在的情况是,loadData
被限制在了useEffect
中了,该如何解决呢?
使用useCallback
const loadData = useCallback(async () => {
const res = await getData();
setItems(res.data);
}, [])
useEffect(() => {
loadData();
}, [loadData]);
const onAdd = () => {
// ...
loadData();
}
这样,就可以在外部调用loadData
了
ps: 如果是删除,那么在确定删除成功后,直接从前端数据中删掉这条数据,也能和远程保持同步。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。