一、使用React
1.通过CDN直接引入react
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="http://static.runoob.com/assets/react/browser.min.js"></script>
直接将代码可添加到head标签中使用
添加的三个依次是React核心API,添加到DOM的方法,和Babel(目的是将JSX语言转义为js可识别的es5代码)
2.直接通过npm下载使用 这个去找教程吧~
二、JSX
学习react JSX可以说是必不可少了,JSX的结构看起来非常眼熟,就是之前使用的JS+HTML 对我们这些新手可谓十分友好
Babel 会把 JSX 转译成一个名为 React.createElement() 函数调用。
以下两种示例代码完全等效:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{className: 'greeting'},
'Hello, world!'
);
其实你编译出来的应该是下面这样的
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world!'
}
};
踩坑:
之前没怎么用过JSX 写了一部分静态页面后发现了一些需要 注意的问题
-
react img中的src不支持直接赋值相对路径 即不支持<img src="./…/src/favicon.ico"/>
解决:
import 方法 import imgURL from ‘./…/images/photo.png’; <img src={imgURL } />require 方法 <img src={require(’./…/images/photo.png’)} />
-
JSX要求标签必须闭合 不然会报错
-
class 要换成 className
-
内联样式style的写法更改 分号改成逗号 ‘ - ’改成小驼峰 属性值用字符串代替…
写个样例
<img src={require("../img/attention-us.png")} alt="" style={{width:116+'px',height:116+'px',position:'relative',left:50+'px'}} />
<div style={{marginLeft:33+'px', fontSize:14+'px'}}>微信公众号</div>
</div>
</div>
<div style={{color:'#fff', textAlign:'center',color: '#fff',opacity: '.7' ,fontSize:'13'+'px',minWidth:'1180'+'px'}}> All Rights Reserved</div>
三、组件
React的组件分为两种 函数组件与 class 组件
函数组件写法:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class组件写法:
class Welcome extends React.Component{
render(){
return <h1>Hello, {this.props.name}</h1>;
}
上述两个组件在 React 里是等效的
HTML: <div id="root"></div>
------------------------------------
js:
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
const element = <Welcome name="Sara" />;
ReactDOM.render(
element,
document.getElementById('root')
);
数据渲染的基本流程是
- 首先通过通过ReactDOM.render()去挂载将组件挂载到根上
- 读取挂载的组件 通过便签去寻找定义它的函数组件或者class组件
这里面还有个props需要着重理解
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)以及子组件(children)转换为单个对象传递给组件,这个对象被称之为 “props”。
简单的来说就是<Welcome name=“Sara” />这个标签里的属性 甚至后面还有它的chlidren等等等 会全部以对象!!!的方式传递到组件的props中
我们调用 ReactDOM.render() 函数,并传入 作为参数。
React 调用 Welcome 组件,并将 {name: ‘Sara’} 作为 props 传入。
Welcome 组件将 <h1>Hello,Sara</h1> 元素作为返回值。
React DOM 将 DOM 高效地更新为<h1>Hello, Sara</h1>。
另外Props 的只读性:组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。
四、State
1.state的作用
State 与 props 类似,但是 state 是私有的,并且完全受控于当前组件。
作用相当于管理当前组件内部数据需要发生真正改变的部分
比如:Date()、input …
原本代码:
class Clock extends React.Component {
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.props.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
添加state后:
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')
);
对比可以发现用了以下几个步骤
- 把 render() 方法中的 this.props.date 替换成 this.state.date
- 添加一个 class 构造函数,然后在该函数中为 this.state 赋初值
- 通过以下方式将 props 传递到父类的构造函数中
- 移除 <Clock /> 元素中的 date 属性
修改state状态:
使用setstate修改状态
this.setState({comment: ‘Hello’});
五、事件处理
React 事件的命名采用小驼峰式(camelCase),而不是纯小写。
使用 JSX 语法时你需要传入一个函数作为事件处理函数,而不是一个字符串。
对比
<button onclick="activateLasers()">
Activate Lasers
</button>
<button onClick={activateLasers}>
Activate Lasers
</button>
另外:不能通过返回 false 的方式阻止默认行为
也就是说 要写成下面的样子
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
可以通过箭头函数和bind都可以解决this的指向问题
六、条件渲染
条件渲染学起来就比较简单了
- 通过变量存储
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
- 三元运算符
- 通过花括号包裹代码,你可以在 JSX 中嵌入任何表达式。这也包括 JavaScript 中的逻辑与 (&&) 运算符。它可以很方便地进行元素的条件渲染。
七、列表和key
列表通过es6中的map方法加 {} 去进行循环遍历
可以是
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
或者
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}
八、组合
为什么没有继承 因为不需要啊~
function Contacts() {
return <div className="Contacts" />;
}
function Chat() {
return <div className="Chat" />;
}
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
ReactDOM.render(
<App />,
document.getElementById('root')
);
这里将<div className=“Chat” /> <div className=“Contacts” />
作为属性传递过去了
因为props是什么都能传~ 只是传出去的格式为对象
······················································································
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
{props.children}
</FancyBorder>
);
}
class SignUpDialog extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSignUp = this.handleSignUp.bind(this);
this.state = {login: ''};
}
render() {
return (
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>
);
}
handleChange(e) {
this.setState({login: e.target.value});
}
handleSignUp() {
alert(`Welcome aboard, ${this.state.login}!`);
}
}
这里的<Dialog></Dialog>是一组标签
里面的内容就是props.children
类似的<FancyBorder></FancyBorder>里面的内容同样作为children通过props.children传递出去
<Dialog title="Mars Exploration Program"
message="How should we refer to you?">
<input value={this.state.login}
onChange={this.handleChange} />
<button onClick={this.handleSignUp}>
Sign Me Up!
</button>
</Dialog>