标签:创建表 let vstat htm tin ogg 实现 ssi event
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React demo</title>
<script src="../build/react.js"></script>
<script src="../build/react-dom.js"></script>
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
function Hello() {
return <h1>Hello world.</h1>;
}
ReactDOM.render(
<Hello/>,
document.getElementById(‘root‘)
)
</script>
</body>
</html>
JSX 是一种 JavaScript 的语法扩展。推荐在 React 中使用 JSX 来描述用户界面,JSX 用来声明 React 当中的元素。
在 JSX 当中的表达式要包含在大括号里。
const element = (
<h1>
Hello, {formatName(user)}!
</h1>
);
推荐在 JSX 代码的外面括上小括号,这样可以防止分号自动插入的 BUG。
在编译之后,JSX 其实会被转化为普通的 JavaScript 对象。
const element = <img src={user.avatarUrl}></img>;
使用了大括号包裹的 JavaScript 表达式时就不要再到外面套引号了。 JSX 会将引号当中的内容识别为字符串而不是表达式。
如果 JSX 标签是闭合式的,那么你需要在结尾处用/>,就好像 XML/HTML 一样:
const element = <img src={user.avatarUrl}/>;
JSX 标签同样可以相互嵌套:
const element = (
<div>
<h1>Hello!</h1>
<h2>Good to see you here.</h2>
</div>
)
警告:
因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名来定义属性的名称,而不是使用 HTML 的属性名称。
例如,class 变成了 className,而 tabindex 则对应着 tabIndex.
Babel 转译器会把 JSX 转换成一个名为 React.createElement() 的方法调用。
下面两种代码的作用是完全相同的:
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
‘h1‘,
{className: ‘greeting‘},
‘Hello, world!‘
);
React.createElement() 这个方法首先会进行一些避免 bug 的检查,之后返回一个类似下面例子的对象:
// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
type: ‘h1‘,
props: {
className: ‘greeting‘,
children: ‘Hello, world‘
}
};
这样的对象被称为“React 元素”。
元素是构成 React 应用的最小单位。
首先定义一个 id 为 root 的 div:
<div id=‘root‘></div>
在此 div 中的所有内容都将由 React DOM 来管理,所以我们将其称之为“根” DOM 节点。
我们用 React 开发应用时一般只会定义一个根节点。
要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:
const element = <h1>Hello,world</h1>;
ReactDOM.render(
element,
document.getElementById(‘root‘)
)
组件可以将 UI 切分为一些独立的、可复用的部件,这样你就只需专注于构建每一个单独的部件。
组件从概念上看就像是函数,它可以接收任意的输入值(称之为“props”),并返回一个需要在页面上展示的 React 元素。
定义一个组件最简单的方式是使用 JavaScript 函数:
// 函数定义组件
function Welcome(props){
return <h1>Helle,{props.name}</h1>;
}
也可以使用 ES6 class 来定义一个组件:
拓展:
ES6 是什么?
ES6:全称 ECMScript 6.0。是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布。
// 类定义组件
class Welcome extents React.Component {
render(){
return <h1>Hello,{this.props.name}</h1>;
}
}
第一步,定义一个 Welcome 组件:
function Welcome(props) {
return <h1>Hello,{props.name}</h1>;
}
第二步,使用该组件创建 React 元素:
const element = <Welcome name=‘kevin‘/>;
第三步,使用 ReactDOM.render() 方法将 React 元素渲染到页面上:
ReactDOM.render(
element,
document.getElementById(‘root‘);
)
组件可以在它的输出中引用其他组件:
function Welcome(props) {
return <h1>Hello,{props.name}</h1>;
}
function App() {
return (
<div>
<Welcome name=‘kevin‘/>
<Welcome name=‘tom‘/>
<Welcome name=‘bob‘/>
</div>
);
}
ReactDOM.render(
<App/>,
document.getElementById(‘root‘)
);
警告:
组件的返回值只能有一个根元素。
props 是不可变的
状态与属性十分相似,但是状态是私有的,完全受控于当前组件。
使用类定义组件,就可以使用局部状态、生命周期钩子等特性。
第一步:使用 ES6 class 定义一个组件
class Clock extents React.component {
render() {
return (
<div>
<h1>Hello,world!</h1>
<h2>It is {this.state.date.toLocaleTimeString}</h2>
</div>
)
}
}
第二步:添加一个类构造函数来初始化状态 this.state
class Clock extents 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() 方法渲染组件到页面
class Clock extents 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.1 中,我们只是添加了一个状态,那么,如何更新状态呢?答案是:使用生命周期方法。
class Clock extents React.component {
constructor(props) {
super(props);
this.state = {date : new Date()};
}
componentDidMount() {
this.timeID = setInterval(
() => this.tick(),1000
);
}
componentWillUnmount() {
clearInterval(this.timeID);
}
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‘)
)
当 Clock 的输出插入到 DOM 中时,React 会调用 componentDidMount() 生命周期方法。上面代码示例中,我们在该方法中设置了一个定时器,每个 1 秒钟调用一次 tick() 方法。
在 tick() 方法中,Clock 组件通过使用包含当前时间的对象调用 setState() 来更新状态。当 React 发现状态已经更新时,会再次调用 ReactDOM.render() 方法更新 DOM。
当 Clock 组件被从 DOM 中移除,React 会调用 componentWillUnmount() 生命周期方法。
构造函数是唯一能够初始化 this.state 的地方。其他地方更薪状态只能使用 this.setState();
不太懂 TODO
不太懂 TODO
父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类。
所以状态通常被成为局部或封装。除了拥有并设置它的组件外,其他组件不可访问。
但组件可以选择将其状态作为属性传递给其子组件。
这通常被称为 自顶向下 或 单向 数据流。任何状态始终由某些特定组件所有,并且该状态导出的任何数据或 UI 只能影响树中 下方 的组件。
例如,传统的 HTML 写法:
<button onclick="activateLasers()">
Activate Lasers
</button>
React 写法:
<button onClick={activateLasers}>
Activate Lasers
</button>
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 绑定 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‘)
)
有两种方式向事件处理程序传递参数,分别是:
<button onClick={(e) => this.deleleRow(id,e)}>Delete Row</button>
<button onClick={this.deleleRow.bind(this,id)}>Delete Row</button>
参数 e 作为 React 的事件对象将会被作为第二个参数进行传递。
箭头函数的方式,事件对象必须显式传递;
绑定的方式,事件对象以及更多的参数将会被隐式传递。值得注意的是,通过绑定的方式向监听函数传参,在类组件中定义的监听组件,事件对象 e 排在所传递参数的后面。
React 中的条件和 JavaScript 中的一致,使用 JavaScript 操作符 if 或 条件运算符 来创建表示当前状态的元素,然后让 React 来更新 UI。
示例:
function UserGreeting() {
return <h1>Welcome back!</h1>;
}
function GuestGreeting() {
return <h1>Please sign up.</h1>
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn){
return <UserGreeting/>
}
return <GuestGreeting/>
}
ReactDOM.render(
<Greeting isLoggedIn={true}/>,
document.getElementById(‘root‘)
)
function Mailbox(props) {
const message = props.message;
return (
<div>
<h1>Hello!</h1>
{message.length > 0 &&
<h2>
You have {message.length} unread message.
</h2>}
</div>
)
}
const message = [‘React‘, ‘Re:React‘,‘Re:Re:React‘];
ReactDOM.render(
<Mailbox message={message}/>,
document.getElementById(‘root‘)
)
true && expression 总是返回 expression,而 false && expression,React 会忽略并跳过它。
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {isLogin: false};
this.login = this.login.bind(this);
}
login() {
this.setState(
prevState => ({
isLogin: !prevState.isLogin
})
);
}
render (){
return (
<div>
<h1>
{this.state.isLogin ? ‘Welcome‘ : ‘Please Login‘}
</h1>
<button onClick={this.login}></button>
</div>
);
}
}
ReactDOM.render(
<Login/>,
document.getElementById(‘root‘)
)
让组件的 render 方法返回 null 即可阻止组件渲染。
function ToDoList(props) {
const things = props.things;
const todolist = things.map((thing) =>
<li key={thing.toString()}>{thing}</li>
);
return (
<ul>{todolist}</ul>
)
}
const things = [1,2,3,4,5];
ReactDOM.render(
<ToDoList things={things}/>,
document.getElementById(‘root‘)
)
在HTML当中,像
<input>
、<textarea>
和<select>
这类表单元素会维持自身状态,并根据用户输入进行更新。但在 React 中,可变的状态通常保存在组件的状态属性中,并且只能用 setState() 方法进行更新。
我们通过使 React 变成一种单一数据源的状态来结合二者。React 负责渲染表单的组件仍然控制用户后续输入时所发生的变化。相应的,其值由 React 控制的输入表单元素称为“受控组件”。
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {value : ‘1‘}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange (event) {
this.setState({
value : event.target.value
})
}
handleSubmit (event) {
alert(‘name is ‘ + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<select value={this.state.value} onChange={this.handleChange}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</label>
<input type="submit" value="Submit"></input>
</form>
)
};
}
ReactDOM.render(
<Form/>,
document.getElementById(‘root‘)
)
<input type=‘text‘>
、<textarea>
、<select>
类似,都是通过传入一个 value
属性来实现对组件的控制。
class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
name : ‘‘,
age: 0
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const target = event.target;
const name = target.name;
const value = target.value;
this.setState({
[name] : value
})
}
handleSubmit(event) {
alert(‘name is ‘ + this.state.name + ‘, and age is ‘ + this.state.age);
event.preventDefault();
}
render () {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" name="name" value={this.state.name} onChange={this.handleChange}/>
</label>
<label>
age:
<input type="text" name="age" value={this.state.age} onChange={this.handleChange}/>
</label>
<input type="submit" value="Submit"/>
</form>
)
}
}
ReactDOM.render(
<Form/>,
document.getElementById(‘root‘)
)
当有多个受控的元素时,可以给每个元素添加一个 name 属性,来让处理函数 event.target.name 的值区分。
标签:创建表 let vstat htm tin ogg 实现 ssi event
原文地址:https://www.cnblogs.com/devywb/p/9054720.html