一. 主要文档
二. 开始使用,体验 react 脚手架
npx create-react-app react-app-demo
cd react-app-demo
yarn start
三. 跟着文档做
- 渲染一个元素
ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById('root'));
- 渲染 JSX 的使用
const name = 'Josh Perez';
const element = <h1>Hello, {name}</h1>;
ReactDOM.render(element, document.getElementById('root'));
- 渲染一个时钟
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);
- 组件部分 Components and Props
// app.js
import React from 'react';
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
export default Welcome;
// index.js
import Welcome from './App';
const element = <Welcome name="Ories" />;
ReactDOM.render(element, document.getElementById('root'));
// app.js
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
// index.js
import Welcome from './App';
const element = <Welcome name="Ories1" />;
ReactDOM.render(element, document.getElementById('root'));
// props 就是父组件传给子组件的值
// return 的时候必须要div包裹起来
function App() {
return (
<div>
<Welcome name="Sara" />
<Welcome name="Cahal" />
<Welcome name="Edite" />
</div>
);
}
- State 和 Lifecycle
// index.js
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()}; // 在这里给state赋值
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
// 在render这个部分,通过this.state.date访问到这个属性
</div>
);
}
}
ReactDOM.render(<Clock />, document.getElementById('root'));
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
componentDidMount() {
this.timerID = setInterval(
() => this.tick(),
1000
);
}
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'));
- 处理事件
helloWorld(){
console.log(1)
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<button onClick={this.helloWorld}>
按钮
</button>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
// 把this进行绑定,点击一个按钮,在react中经常会出现bind this这种情况,
// 因为点击一个按钮,其event经常会指向dom元素,而不是指向react class本身,所以需要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')
);
- 条件渲染
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
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 UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
);
}
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
let button;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
- List 和 Keys
const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
<li key={number.toString()}>{number}</li>
// 要加keys
);
ReactDOM.render(
<ul>{listItems}</ul>,
document.getElementById('root')
);
- Forms 表单提交案例
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value.toUpperCase()} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
- 状态提升
- 水有没有开
function BoilingVerdict(props) {
if (props.celsius >= 100) {
return <p>The water would boil.</p>;
}
return <p>The water would not boil.</p>;
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {temperature: ''};
}
handleChange(e) {
this.setState({temperature: e.target.value});
}
render() {
const temperature = this.state.temperature;
return (
<fieldset>
<legend>Enter temperature in Celsius:</legend>
<input
value={temperature}
onChange={this.handleChange} />
<BoilingVerdict
celsius={parseFloat(temperature)} />
</fieldset>
);
}
}
ReactDOM.render(
<Calculator />,
document.getElementById('root')
);
- 组合和继承
- 组合
// index.js
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' props.color}>
{props.children}
</div>
);
}
function WelcomeDialog() {
return (
<FancyBorder color="red">
// 这里可以改成green, blue
<h1 className="Dialog-title">
Welcome
</h1>
<p className="Dialog-message">
Thank you for visiting our spacecraft!
</p>
</FancyBorder>
);
}
ReactDOM.render(
<WelcomeDialog />,
document.getElementById('root')
);
// index.css
.FancyBorder {
border: 1px solid;
}
.FancyBorder-red{
border-color: red;
}
.FancyBorder-blue{
border-color: blue;
}
.FancyBorder-green{
border-color: green;
}
- 继承
function FancyBorder(props) {
return (
<div className={'FancyBorder FancyBorder-' props.color}>
{props.children}
</div>
);
}
function Dialog(props) {
return (
<FancyBorder color="blue">
<h1 className="Dialog-title">
{props.title}
</h1>
<p className="Dialog-message">
{props.message}
</p>
</FancyBorder>
);
}
function WelcomeDialog() {
return (
<Dialog
title="Welcome"
message="Thank you for visiting our sda!" />
);
}
四. TypeScript 简介
- 案例一
function greeter(person: string) {
return "Hello, " person;
}
let user = "Jane User"; // 如果在这个地方改成bool,数字,下面一行会报错
document.body.textContent = greeter(user);
- 定义 Person 的对象类型
// interface 主要用在对象上面
interface Person {
firstName: string;
lastName: string;
}
function greeter(person: Person) {
return "Hello, " person.firstName " " person.lastName;
}
let user = { firstName: "Jane", lastName: "User" };
document.body.textContent = greeter(user);
五. 构建 React Antd Typescript 项目
yarn create react-app potato --template typescript
yarn add antd
// app.css
@import '~antd/dist/antd.css';
最后,个人微信,欢迎交流!