当前位置: 首页 > 科技观察

我老板:你根本不懂React!

时间:2023-03-18 20:31:57 科技观察

前言我已经使用React多年了,我确信我对它非常了解,但是最近我的老板对我说,“你不知道React,你对它一无所知。”我生他的气,但他指出了我程序中的三个错误。我现在记录下来,分享给还不知道的朋友。1、你知道“&&”的用法吗?在React程序中,我经常使用“&&”操作符来决定是否显示内容,如下:constApp=()=>{const[list,setList]=useState([])//模拟请求数据setTimeout(()=>{setList(['fatfish','medium'])},2000)return({list.length&&}

)}我的老板:“你不知道&&”运算符的特点吗?当请求还没有成功返回时,会直接渲染“0”。我不服气,因为我一直都是这样写代码的,从来没有出错过。为了证明老大错了,我写了下面的例子。constList=({list=[]})=>{return({list.map((name)=>{return{name}
})}
)}constApp=()=>{const[list,setList]=React.useState([])//模拟请求数据setTimeout(()=>{setList(['fatfish','medium'])},3000)return(list.length&&)}ReactDOM.render(,document.getElementById('app'))天哪!老板说的对,页面一开始显示0,3秒后显示列表。为什么?来自MDN的提示:“当且仅当所有操作数都为真时,一组布尔操作数的逻辑与(&&)运算符(逻辑合取)为真。否则为假。”更一般地,运算符返回从左到右求值时遇到的第一个假操作数的值,或者如果它们都为真,则返回最后一个操作数的值。例子如下:constx1=0constx2='fatfish'constx3=1constx4='medium'console.log(x1&&x2)//0console.log(x3&&x4)//medium现在终于明白为什么了我写这段代码会出错。原因如下:list.length&&0&&//0怎么解?我找到了三种方法来解决这个问题。希望你不要重蹈我的覆辙,祝福你。//1.Convertlist.lengthtoboolean!!list.length&&//2.使用三元表达式和nulllist.length?:null//3.由特定的逻辑控制list.length>=1&&2."props.children"的奇怪行为我猜你写过类似的代码。将内容传递给组件时,会显示“children”。如果没有,将显示一个空的工具提示。像这样:constContainer=({children})=>{if(children){return(

children的内容是:

{children}
)}else{return(empty)}}我的老板:“你必须小心'children'属性,它会导致逻辑异常!像下面的情况相同的。”1).空列表数据你认为这个例子会显示什么——“空”?不幸的是,答案是另一个。你是不是也觉得不可思议?朋友们,我们必须非常小心props.children。否则,老板可能会扣你的工资。constContainer=({children})=>{if(children){return(

children的内容是:

{children})}else{return(empty)}}constApp=()=>{const[list,setList]=React.useState([])return({list.map((name)=>{return{name}})})}ReactDOM。render(,document.getElementById('app'))为什么?让我们向“Container”组件添加一行代码,并尝试打印出孩子们是什么!constContainer=({children})=>{console.log(children,'children')//...}是的,你是对的。此时“children”是一个空数组,所以显示的是“children的内容是:”,而不是“empty”。怎么解决?使用React.Children.toArray很容易解决这个问题,然后你会看到显示“空”。所以如果你真的需要用children作为条件判断,我建议你使用这个方法!constContainer=({children})=>{//if(children){//注意这里if(React.Children.toArray(children).length){return(

children的内容是:

{children})}else{return(empty)}}3.关于挂载和更新Switching组件的问题through状态在React中很常见,然而,这个小东西也会让你感到困惑。在下面的代码中,你认为当你切换name的值时,一个Demo组件会被卸载而另一个会被挂载吗?类演示扩展React.Component{componentDidMount(){console.log('componentDidMount',this.props.name);}componentDidUpdate(){console.log('componentDidUpdate',this.props.name);}render(){return(
{this.props.name}
)}}constApp=()=>{const[name,setName]=React.useState('fatfish')constonClick=()=>{setName(name==='fatfish'?'medium':'fatfish')}return({name==='fatfish'?:}click)}ReactDOM.render(,document.getElementById('app'))我录制了一个简短的gif来告诉你真相。也可以通过CodePen试试,https://codepen.io/qianlong/pen/NWywodVWhy?虽然我们写了两个Demo组件,假设它们会分别挂载和更新,但React认为它们是同一个组件,所以componentDidMount只会执行一次。怎么解决?但是当我们要写两个相同的组件但是传递不同的参数时,我们应该怎么办呢?是的,你应该为这两个组件添加不同的键,这样React就会认为它们是不同的组件。componentDidMount也是单独执行的。让我们试试://...//注意这里的名称==='fatfish'?://...你也可以通过CodePen试试,https://codepen.io/乾隆/pen/NWywodV.