JSX
内大括号可以写任意 js 代码,同理可以调用变量
ReactDOM.render
将指定 JSX 渲染到指定 DOM 上面去
const name = "Josh Perez";
const element = Hello, {name}
;ReactDOM.render(element, document.getElementById("root"));
JSX 可以当做参数传入,或者返回
// 变量直接赋值JSX完全没问题
const element = ;// user这个形参可以直接传入JSX
function getGreeting(user) {return Hello, Stranger.
;
}
两种创建 JSX 的方法
// 方法一
const element = Hello, world!
;// 方法二
const element = React.createElement("h1",{ className: "greeting" },"Hello, world!"
);
react 的组件定义最方便的方法是:直接用函数,接受一个形参即 props
自定义组件的属性直接传给形参 props,如下代码传参后的结果是: {name:'Sara'}
组件名必须大写开头
// 顶一个组件,props为参数
function Welcome(props) {return Hello, {props.name}
;
}// 针对自定义组件,所有的属性都统一作为参数传递给props
const element = ;
ReactDOM.render(element, document.getElementById("root"));
把组件单独抽离出来便于复用,这是一个好习惯!
若要使用 state 控制组件生命周期,请改用 class 来声明组件而非函数式
在同一 DOM 内多次调用 render 时,class 式声明的组件在其生命周期内只会存在一个实例!
class Clock extends React.Component {render() {return (Hello, world!
It is {this.props.date.toLocaleTimeString()}.
);}
}
this.props
与 this.state
是 react 内部字段
这是一个完整实现每隔 1s 更新一次时间的组件 Clock
class Clock extends React.Component {// 组件的构造函数constructor(props) {super(props);// state是内部值,直接向里面丢东西this.state = { date: new Date() };}// 挂载完毕,开启间隔计时器,每1s执行一次方法tick()componentDidMount() {this.timerID = setInterval(() => this.tick(), 1000);}// 卸载前清除计时器componentWillUnmount() {clearInterval(this.timerID);}// 间隔更新函数,setState(差不多和微信小程序一个意思)修改值tick() {this.setState({date: new Date(),});}// render里面渲染DOMrender() {return (Hello, world!
It is {this.state.date.toLocaleTimeString()}.
);}
}// 渲染,没啥好说的
ReactDOM.render( , document.getElementById("root"));
state 注意事项
setState
方法,否则改数据后不会重新渲染!在 react 中,阻止组件的默认行为只能通过 js 代码实现
下面将一个函数抽离,并使用 preventDefault 阻止组件默认行为
function ActionLink() {function handleClick(e) {// 阻止组件的默认行为e.preventDefault();console.log("The link was clicked.");}return (handleClick}>Click me);
}
class 式创建自定义组件时,其中的方法不会自动绑定 this,所以需要我们手动改变其 this 指向到对应的 class 里面去
原理:当你调用一个方法时若不在结尾添加一个小括号,就必须明确其 this 指向,如下代码,我们调用 handleClick
方法时没有加小括号,故需要在 constructor
函数内改变其 this 指向
class Toggle extends React.Component {constructor(props) {...// 改变class内的方法handleClick的this指向为本classthis.handleClick = this.handleClick.bind(this);}handleClick() {...}render() {return (// 此情况下必须要为方法handleClick指定this指向);}
}
这是两种等价的,为方法确定正确的 this 指向的写法
与运算符&&
react 基本条件运算,根据之前我们所学知识,花括号内可以填写任意表达式;故以下代码判断,当 unreadMessages.length > 0
条件成立时就会执行 &&
运算符后面的 JSX
function Mailbox(props) {const unreadMessages = props.unreadMessages;return (Hello!
{unreadMessages.length > 0 && (You have {unreadMessages.length} unread messages.
)});
}
和 vue 一致,你也可以使用三元运算符
render() {const isLoggedIn = this.state.isLoggedIn;return (The user is {isLoggedIn ? 'currently' : 'not'} logged in.);
}
如果你想让组件不渲染,直接返回 null
return null
react 的列表渲染比较朴实一点,直接调用元素 map 迭代渲染
但和 vue 一样,最好使用 key,否则会出现警告
function NumberList(props) {const numbers = props.numbers;// 使用map取出numbers内部的所有值,渲染到指定JSXconst listItems = numbers.map((number) => (// 万不得已的情况下可以直接拿值作为keynumber.toString()}>{number} ));return {listItems}
;
}const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(numbers} />,document.getElementById("root")
);
不过官方推荐数据若没有给出 id 值的话,可以拿 map 的索引值作为 key
// 这里的todo为值,而index是map函数为我们生成的对应索引
const todoItems = todos.map((todo, index) => index}>{todo.text} );
关于 key 使用的注意事项
直接内联 return 一个列表渲染的 JSX,省去了冗余的中间变量
function NumberList(props) {const numbers = props.numbers;return ({numbers.map((number) => (number.toString()} value={number} />))}
);
}
react 中的表单采用将所有数值都统一由 state 进行管理
代码解释:
表单 form 中的 input,其 value 属性直接由顶层 state 管理;onChange
也是由函数 handleChange
动态更新 state 中指定属性的值;
由于构造函数内 state 已经初始化为空字符串,故不用担心渲染 input 时会出错!
class NameForm extends React.Component {constructor(props) {super(props);this.state = { value: "" };// 没有小括号的函数调用必须要明确指定this指向// 这里没有使用箭头函数的方法,而是使用bind绑定this.handleChange = this.handleChange.bind(this);this.handleSubmit = this.handleSubmit.bind(this);}handleChange(event) {this.setState({ value: event.target.value });}// 表单提交操作handleSubmit(event) {alert("提交的名字: " + this.state.value);// 阻止默认的表单post或者get操作,由该方法进行自定义指定event.preventDefault();}render() {return ();}
}
对于文本域 textarea
,我们不再向其内部写标签,直接使用 value
作为该文本域的内容
select 组件里面的 value 直接指代当前激活的是哪一个 option,他的值等于当前几乎跌 option 的 value 值
当存在多个 input 时,为他们添加 name 属性,设置不同名字,并在 onchange 函数内部进行判断即可动态更新对应的 state
handleInputChange(event) {...// 获取当前input的name属性值const name = target.name;// 根据键值对的方法,赋予指定name的值为valuethis.setState({[name]: value});}render() {return ();}