import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
hello world
ReactDOM.render(
<h1>hello, wolrd!</h1>,
document.getElementById('root')
)
嵌入表达式
const name = 'gjyao'
const element = <h1>Hello, {name}</h1>
function formatName(user){
return user.firstName + ' ' + user.lastName
}
const user = {
firstName: 'Harper',
lastName: 'Perez'
}
const element = (
<h1>
Hello, {formatName(user)}!
</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)
函数组件与class组件
function Welcome(pros) {
return <h1>Hello, {pros.name}</h1>;
}
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>
}
}
以上两种组件都是等效的
const element = <Welcome name="gjyao" />;
ReactDOM.render(
element,
document.getElementById('root')
);
组合组件
function App() {
return (
<div>
<Welcome name="Sara" ></Welcome>
<Welcome name="Cahal" ></Welcome>
<Welcome name="Edfi" ></Welcome>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));
State
class Clock extends React.Component{
// Class组件应始终使用props参数来调用父类的构造函数
constructor(props){
//将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, wolrd!</h1>
<h2>现在是{this.state.date.toLocaleTimeString()}。</h2>
</div>
)
}
}
每个组件相互独立
function App(){
return(
<div>
<Clock/>
<Clock/>
<Clock/>
</div>
)
}
ReactDOM.render(<App />, document.getElementById("root"));
事件处理
function ActionLink() {
function handleClick(e) {
//e是一个合成事件
e.preventDefault()
console.log("the link was clicked")
}
return (
<a href="#" onClick={handleClick}>
Click Me
</a>
)
}
ReactDOM.render(<ActionLink />, document.getElementById("root"))
class Toggle extends React.Component{
constructor(props){
super(props)
this.state = {isToggle: true}
// 为了在回调中使用 `this`,这个绑定是必不可少的
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.setState(state=>({
isToggle: !state.isToggle
}))
}
render(){
return (
<button onClick={this.handleClick}>
{this.state.isToggle ? 'ON' : 'OFF'}
</button>
)
}
}
class Toggle extends React.Component{
constructor(props){
super(props)
this.state = {isToggle: true}
}
//public class fields 语法,
//此语法确保 `handleClick` 内的 `this` 已被绑定。
handleClick = ()=> {
this.setState(state=>({
isToggle: !state.isToggle
}))
}
render(){
return (
<button onClick={this.handleClick}>
{this.state.isToggle ? 'ON' : 'OFF'}
</button>
)
}
}
ReactDOM.render(<Toggle />, document.getElementById("root"))
条件渲染
function LoginButton(props) {
return (
<button onClick={props.onClick}>
Login
</button>
)
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
Logout
</button>
)
}
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 />;
}
有状态组件
class LoginControl extends React.Component{
constructor(props){
super(props)
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"))
与运算符
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
ReactDOM.render(
<Mailbox unreadMessages={messages} />,
document.getElementById('root')
);
阻止渲染
function WarningBanner(props) {
if (!props.warn) {
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {showWarning: true};
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(state => ({
showWarning: !state.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
基础列表组件
function NuberList(props) {
const numbers = props.numbers
const listItems = numbers.map(number =>
<li key={number.toString()}>{number}</li>
)
return (
<ul>{listItems}</ul>
)
}
const number = [1, 2, 3, 4, 5]
ReactDOM.render(
<NuberList numbers={number} />,
document.getElementById('root')
);
受控组件
class NameForm extends React.Component {
constructor(props) {
super(props)
this.state = {value: ''}
}
handleChange = (event) => {
this.setState({value: event.target.value})
console.log(this.state)
}
handleSubmit = (event) => {
alert('提交的名字: ' + this.state.value)
event.preventDefault()
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
名字:
<input type="text" value={this.state.value} onChange={this.handleChange}></input>
</label>
<input type="submit" value="提交"></input>
</form>
)
}
}
ReactDOM.render(
<NameForm />,
document.getElementById('root')
);
处理多个输入
class Reservation extends React.Component {
constructor(props) {
super(props)
this.state = {
isGoing: true,
numberOfGuests: 2
}
}
handleInputChange = (event) => {
const target = event.target
const value = target.type === 'checkbox' ? target.checked : target.value
const name = target.name
//使用了 ES6计算属性名称的语法更新给定输入名称对应的 state 值
this.setState({
[name]: value
})
}
render() {
return (
<form>
<label>
参与:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange}
/>
</label>
<br />
<label>
来宾人数:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange}
/>
</label>
</form>
)
}
}
ReactDOM.render(
<Reservation />,
document.getElementById('root')
);
状态提升
const scaleNames = {
c: "Celsius",
f: "Fahrenheit"
};
function toCelsius(fahrenheit) {
return ((fahrenheit - 32) * 5) / 9;
}
function toFahrenheit(celsius) {
return (celsius * 9) / 5 + 32;
}
function tryConvert(temperature, convert) {
const input = parseFloat(temperature);
if (Number.isNaN(input)) {
return "";
}
const output = convert(input);
const rounded = Math.round(output * 1000) / 1000;
return rounded.toString();
}
class TemperatureInput extends React.Component {
constructor(props) {
super(props);
this.state = {
temperature: ""
};
}
handleChange = e => {
this.props.onTemperatureChange(e.target.value);
};
render() {
const temperature = this.props.temperature;
const scale = this.props.scale;
return (
<fieldset>
<legend>Enter temperature in {scaleNames[scale]}:</legend>
<input value={temperature} onChange={this.handleChange} />
</fieldset>
);
}
}
class Calculator extends React.Component {
constructor(props) {
super(props);
this.state = { temperature: "", scale: "c" };
}
handleCelsiusChange = temperature => {
this.setState({ scale: "c", temperature });
};
handleFahrenheitChange = temperature => {
this.setState({ scale: "f", temperature });
};
render() {
const scale = this.state.scale;
const temperature = this.state.temperature;
const celsius =
scale === "f" ? tryConvert(temperature, toCelsius) : temperature;
const fahrenheit =
scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature;
return (
<div>
<TemperatureInput
scale="c"
temperature={celsius}
onTemperatureChange={this.handleCelsiusChange}
/>
<TemperatureInput
scale="f"
temperature={fahrenheit}
onTemperatureChange={this.handleFahrenheitChange}
/>
</div>
);
}
}
ReactDOM.render(<Calculator />, document.getElementById("root"));