React基础
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
<body> <div id="root"></div> </body>
<script type="text/babel">
...
1.最基础的语法
ReactDOM.render(
"asd",document.getElementById('root')
);
2.JSX表达式,元素
const element = <h1>hello</h1>;//jsx表达式
//Babel 将JSX编译成 React.createElement() 调用,最终编译为一个对象
ReactDOM.render(element,document.getElementById("root"));
3.函数式组件,渲染(react使用diff算法,只更新必要更新的部分)
function tick(){
const element = (<div><h1>hi</h1>{new Date().toLocaleString()}</div>);
ReactDOM.render(element,document.getElementById('root'));
}
setInterval(tick,1000);
4.类组件,state
//用类定义的组件有一些额外的特性。 这个”类专有的特性”, 指的就是局部状态state。
属性:
class Clock extends React.Component {
render(){
return(
<div>
<h1>Hello,world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
)
}
}
ReactDOM.render(
<Clock date={new Date()}/>,document.getElementById('root')
);
状态:
class Clock extends React.Component {
constructor(props){
super(props);
this.state = {date: new Date()};
}
render(){
return(
<div>
<h1>Hello,world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,document.getElementById('root')
);
5.生命周期
componentDidMount(){}
componentWillUnMount(){}
一个复杂的示例:
class Clock extends React.Component {
constructor(props){
super(props);
this.state = {date: new Date()};
}
//当第一次渲染到DOM时,挂载
componentDidMount(){
//除了props与state,如果需要存储一些不用于视觉输出的内容,则可以手动向类中添加额外的字段。
this.timerID = setInterval(
()=>this.tick(),
1000
);
}
//当产生的DOM销毁时,卸载
componentWillUnMount(){
clearInterval(this.timerID);
}
tick(){
this.setState({
date: new Date()
});
}
render(){
return(
<div>
<h1>Hello,world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(
<Clock />,document.getElementById('root')
);
6.处理事件
7.列表和键function ActionLink() { function handleClick(e) { e.preventDefault(); console.log('The link was clicked.'); } return ( <a href="#" onClick={handleClick}> Click me </a> );
}
·多组件渲染
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li>{number}</li>
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
·keys在同辈元素中必须是唯一的(并不需要全局唯一)
8.表单
·受控组件(Controlled Components)
通俗的讲就是给input的Value设为{this.state.value} ,在组件的构造函数中,this.state = {value:''}
·<input type="text">
·<textarea>
·<select>
<option></option>
<option></option>
</select>
·<input type="file">
·处理多个输入元素
·受控input组件的null值
9.状态提升
·在 React 中,共享 state(状态) 是通过将其移动到需要它的组件的最接近的共同祖先组件来实现的。
在一个 React 应用中,对于任何可变的数据都应该循序“单一数据源”原则。通常情况下,state 首先被添加到需要它进行渲染的组件。然后,如果其它的组件也需要它,你可以提升状态到它们最近的祖先组件。你应该依赖 从上到下的数据流向 ,而不是试图在不同的组件中同步状态。
提升状态相对于双向绑定方法需要写更多的“模板”代码,但是有一个好处,它可以更方便的找到和隔离 bugs。
10.组合VS继承
组合:(√)
·一些组件在设计前无法获知自己要使用什么子组件,我们建议这种组件使用特别的
children
prop 来直接传递 子元素到他们的输出中:父组件中{props.children}
子组件中可以随便写一些标签
·继承:(X)
在 Facebook ,我们在千万的组件中使用 React,我们还没有发现任何用例,值得我们建议你用继承层次结构来创建组件。
组件可以接受任意的 props(属性) ,包括原始值、React 元素,或者函数。
11.React编程思想
·单一职责原则
一个组件理想情况下只处理一件事。如果一个组件持续膨胀,就应该将其拆分为多个更小的组件中。
步骤1:将 UI 拆解到组件层次结构中
步骤2: 用 React 构建一个静态版本
要构建你 app 的一个静态版本,用于渲染数据模型, 您将需要构建复用其他组件并使用 props 传递数据的组件。props 是将数据从 父级组件 传递到 子级 的一种方式。如果你熟悉 state 的概念,在构建静态版本时 *不要使用 *state ** 。state 只用于交互,也就是说,数据可以随时被改变。由于这是一个静态版本 app,所以你并不需要使用 state 。
步骤3: 确定 UI state(状态) 的最小(但完整)表示
想想我们的示例应用中的所有数据。 我们有:
- 原始产品列表
- 用户输入的搜索文本
- 复选框的值
- 过滤后的产品列表
请简单地提出有关每个数据的 3 个问题:
- 是否通过 props(属性) 从父级传入? 如果是这样,它可能不是 state(状态) 。
- 是否永远不会发生变化? 如果是这样,它可能不是 state(状态)。
- 是否可以由组件中其他的 state(状态) 或 props(属性) 计算得出?如果是这样,则它不是 state(状态)。
原始的产品列表作为 props(属性) 传递,所以它不是 state(状态) 。搜索文本和复选框似乎是 state(状态) ,因为它们会根据用户的输入发生变化,并且不能从其他数据计算得出。 最后,过滤后的产品列表不是 state(状态) ,因为它可以通过结合 原始产品列表 与 搜索文本 和 复选框的值 计算得出。
所以最终,我们的 state(状态) 是:
- 用户输入的搜索文本
- 复选框的值
步骤4:确定 state(状态) 的位置
现在,已经确定了应用所需 state(状态) 的最小集合。接下来,需要确定是哪个组件可变,或者说哪个组件拥有这些 state(状态) 。
记住:React 单向数据流在层级中自上而下进行。这样有可能不能立即判断出状态属于哪个组件。这常常是新手最难理解的一部分,试着按下面的步骤分析操作:
对于你应用中的每一个 state(状态) :
- 确定每个基于这个 state(状态) 渲染的组件。
- 找出公共父级组件(一个单独的组件,在组件层级中位于所有需要这个 state(状态) 的组件的上面。愚人码头注:父级组件)。
- 公共父级组件 或者 另一个更高级组件拥有这个 state(状态) 。
- 如果找不出一个拥有该 state(状态) 的合适组件,可以创建一个简单的新组件来保留这个 state(状态) ,并将其添加到公共父级组件的上层即可。
//当创建一个大组件库的时候,你将感激模块化、结构清晰和可以重用的代码,同时你的代码行数会慢慢减少。:)