问题
- index.js: Adjacent JSX elements must be wrapped in an enclosing tag (3:0)
索引:js:相邻JSX元素必须包装在一个封闭的标签
<Page user={user} avatarSize={avatarSize} />// ... which renders ...<PageLayout user={user} avatarSize={avatarSize} />// ... which renders ...<NavigationBar user={user} avatarSize={avatarSize} />// ... which renders ...<Link href={user.permalink}><Avatar user={user} size={avatarSize} /></Link>
解决方法:该问题没有加一个封闭的标签,加了一个
(<div><Page user={user} avatarSize={avatarSize} />// ... which renders ...<PageLayout user={user} avatarSize={avatarSize} />// ... which renders ...<NavigationBar user={user} avatarSize={avatarSize} />// ... which renders ...<Link href={user.permalink}><Avatar user={user} size={avatarSize} /></Link></div>)
function定义了一个(组件的)函数,return返回对应的 html
function Avatar(props) {return (<img className="Avatar"src={props.user.avatarUrl}alt={props.user.name}/>);}
优化 html 布局
(1)初始状态 一个div 包括 1,2,3 三个 div ,2,3已经没有优化的部分,1可以优化
<div className="Comment"><div1 className="UserInfo"><imgclassName="Avatar"src={props.author.avatarUrl}alt={props.author.name}/><div1-1 className="UserInfo-name">{props.author.name}</div></div><div2 className="Comment-text"> {props.text}</div><div3 className="Comment-date">{formatDate(props.date)}</div></div>
(2)第一步优化,把 img中的三部分优化成一部分。
<div className="Comment"><div1 className="UserInfo"><Avatar user={props.author} /><div1-1 className="UserInfo-name">{props.author.name}</div></div><div2 className="Comment-text">{props.text}</div><div3 className="Comment-date">{formatDate(props.date)}</div></div>
(3)第二次优化。把img 和 1-1进行优化成 props-author。优化结束。
- ReactDom.render 显示的是const的时候,如果想对 return 的 html进行 css 修饰,必须对其进行属性的修改,因为return返回的是 html的属性方法。
- 单论图形:h1>h=p=div,等级上 :div>p>h>h1
<div id="root"></div>
h {font-size:40px;border: 1px solid red;text-align:center}h1 {width:200px;height:100px;font-size:40px;border: 1px solid red;text-align:center}h2 { font-size:40px;border: 1px solid red;text-align:center}p { font-size:40px;border: 1px solid red;text-align:center}
/*function tick() {const element = (<div><h1>Hello, world!</h1><h2>It is {new Date().toLocaleTimeString()}.</h2></div>);ReactDOM.render(element,document.getElementById('root'));}setInterval(tick, 1000);*///执行结果:Hello, world!//It is 2019/3/2 下午3:35:17.//p和h1、h2一样大,h比h1小。//封装钟的样子function Clock(props) {return (<div><h>It is {props.date.toLocaleTimeString()}.</h><h1 className="element">Hello, world!</h1><h2>It is {props.date.toLocaleTimeString()}.</h2><p >bye</p></div>);}function tick() {ReactDOM.render(<Clock date={new Date()} />,document.getElementById('root'));}setInterval(tick, 1000);
this 方法:指针
// Wrong 道具和。状态可能是异步更新,你不应该依赖于它们的值计算下一个状态//使用第二个形式的设置状态(),它接受一个函数,而不是一个对象。这个函数将收到之前的状态作为第一个参数,//和当时的道具应用更新为第二个参数:/*this.setState({counter: this.state.counter + this.props.increment,});*/// Correctthis.setState((state, props) => ({counter: state.counter + props.increment}));//用一个箭头上面函数,但它也与常规功能// Correctthis.setState(function(state, props) {return {counter: state.counter + props.increment};});
this 绑定 :具体解释+链接
- this 方法:错误解释和变式。
class Toggle extends React.Component{constructor(props){super(props);this.state={isToggleOn:true};//在构造函数中,利用Function.bind()函数将类中已有的handleClick函数再次绑定了一下this//1.如果你不绑定this.handleClick方法,那么在事件发生并且精确调用这个方法时,方法内部的this会丢失指向。//2.这不是React的原因,这是JavaScript中本来就有的。如果你传递一个函数名给一个变量,然后通过在变量后加括号()来调用这个方法,//此时方法内部的this的指向就会丢失this.handleClick=this.handleClick.bind(this);}handleClick(){this.setState(prevState=>({isToggleOn:!prevState.isToggleOn}));}render(){return(<button onClick={this.handleClick}>{this.state.isToggleOn ?'ON':'OFF'}</button>);}}ReactDOM.render(<Toggle/>,document.getElementById('root'));
如果调用绑定惹恼你,有两种方法可以绕过这个限制。如果您使用的是语法实验公共类字段,你可以使用类字段正确绑定回调:
加()=>方法可以代替指针
class LoggingButton extends React.Component {// This syntax ensures `this` is bound within handleClick.// Warning: this is *experimental* syntax.handleClick = () => {console.log('this is:', this);}render() {return (<button onClick={this.handleClick}>Click me</button>);}}
Condition Render条件渲染
在React中,您可以创建不同的组件来封装您需要的行为。然后,根据应用程序的状态,只能渲染其中的一些。
React中的条件呈现与JavaScript中的条件工作方式相同。使用诸如if或条件运算符之类的javascript运算符创建表示当前状态的元素,并让react更新UI以匹配它们。
可以使用变量来存储元素。这可以帮助你在输出的其余部分不变的情况下有条件地呈现组件的一部分
虽然声明变量并使用if语句是有条件地呈现组件的好方法,但有时可能希望使用较短的语法。在JSX中有几种内联条件的方法:
带逻辑和运算符的内联if。
可以将任何表达式用大括号括起来,从而将它们嵌入到JSX中。这包括javascript逻辑&&运算符。它可以方便地有条件地包括一个元素。
因为在javascript中,true&&expression总是计算为expression,false&&expression总是计算为false。
因此,如果条件为真,那么&&之后的元素将出现在输出中。如果它是错误的,那么react将忽略并跳过它。
带条件运算符的inline if else
另一种有条件地内联呈现元素的方法是使用javascript条件运算符条件?真:假。
就像在JavaScript中一样,根据自己和团队认为更具可读性的内容选择合适的样式是由您决定的。还要记住,当条件变得过于复杂时,可能是提取组件的好时机。
阻止组件呈现
在极少数情况下,可能希望某个组件隐藏自己,即使它是由另一个组件呈现的。若要执行此操作,将返回空值而不是其呈现输出
从组件的呈现方法返回空值不会影响组件生命周期方法的激发。例如,仍将调用ComponentDidUpdate
List and key 列表和键
首先,让我们回顾一下如何在JavaScript中转换列表。
我们使用map()函数获取一个数字数组并使其值加倍。我们将map()返回的新数组赋给double变量并记录它:
在react中,将数组转换为元素列表几乎是相同的。
呈现多个组件
可以使用大括号构建元素集合并将它们包含在JSX中
键有助于确定哪些项已更改、添加或删除。应为数组内的元素提供键,以使元素具有稳定的标识
如果渲染项没有稳定的ID,则可以使用项索引作为密钥作为最后的手段
如果项的顺序可能更改,我们不建议对键使用索引。这会对性能产生负面影响,并可能导致组件状态问题。查看RobinPokorny的文章,深入了解使用索引作为键的负面影响。如果选择不为列表项指定显式键,那么react将默认为使用索引作为键。
用键提取组件
键只在周围数组的上下文中有意义
一个好的经验法则是map()调用中的元素需要键。
键只能在同级中唯一
数组中使用的键在其同级中应该是唯一的。不过,它们不需要全球独一无二。当我们生成两个不同的数组时,可以使用相同的键:
键用作反应的提示,但它们不会传递给您的组件。若组件中需要相同的值,请将其作为具有不同名称的属性显式传递JSX允许在大括号中嵌入任何表达式,以便我们可以内联map()结果:
有时这会导致代码更清晰,但这种风格也会被滥用。像在JavaScript中一样,由您决定是否值得为可读性提取一个变量。请记住,如果map()主体过于嵌套,则可能是提取组件的好时机
