在开始学习 React 之前,您需要具备以下基础知识:
HTML5
CSS
JavaScript
基本含义:
jsx特点
花括号{}
别名:className 代替class ,htmlFor代替html。
html被编译成什么呢?
这里,Welcome不是字符串,是一个构造方法,所以首字母是大写
这些object也就是ReactElement对象,通过React.createElement方法与conponent的jsx代码互换,同样可以运行。
综上所述:
Props/State/Forms 属性和状态
Props(属性)
npm install bootstrap --save
例子:
函数式声明方式:
const NameCard = {props}=>{
return(内容)
}
纯函数值不能被改变
react-Component,所有的组件必须像纯函数一样使用props,在一个组件中props是不可变的,state却可以在不改变上述条件下使组件动态的输出
state状态
比如下拉菜单的显示隐藏,一组数据的加载(loading,再显示数据),之前只有一种方法更新界面,就是调用ReactDOM.Rander方法.
class LikesButton extends React.Component{
constructor(props){
super(props)
this.state={
likes:0
}
this.increasLikes=this.increasLikes.bind(this)
}
increasLikes(){
// this.setState({
// likes:++this.state.likes
// })
alert("你好")
console.log(this) // this是没有绑定的返回undefined
}
render() {
return(
<div>
<button
type="button"
className="buttons btn-lg"
onClick={this.increasLikes}
>
{this.state.likes}</button>
</div>
)
}
}
export default LikesButton;
在js的类中,this是没有自动绑定的,所以当访问回调函数onClick={this.increasLikes}时,返回是undefined,手动绑定
this.increasLikes=this.increasLikes.bind(this)
方法2:
es6有箭头函数的概念,就不需要额外绑定了
onClick={()=>{this.increasLikes()}}
最终效果:
class LikesButton extends React.Component{
constructor(props){
super(props)
this.state={
likes:0
}
}
increasLikes(){
this.setState({
likes:++this.state.likes
})
}
render() {
return(
<div>
<button
className="buttons"
onClick={()=>{this.increasLikes()}}
>{this.state.likes}</button>
</div>
)
}
}
export default LikesButton;
import React from 'react'
class DigitalClock extends React.Component{
constructor(props){
super(props)
this.state={
date:new Date()
}
}
componentDidMount() {
this.timer=setInterval(()=>{
this.setState({
date:new Date()
})
},1000)
}
componentDidUpdate(prevProps, prevState, snapshot) {
console.log(prevState)
}
componentWillUnmount() {
clearInterval(this.timer)
}
render() {
return(
<div>
<h1>{this.state.date.toLocaleTimeString()}</h1>
</div>
)
}
}
export default DigitalClock;
import React from 'react'
//受控组件
class CommentBox2 extends React.Component{
constructor(props){
super(props)
this.handlesub=this.handlesub.bind(this)
this.state={
value:''
}
}
handlesub(ev){
alert(this.state.value)
ev.preventDefault()
}
render() {
return(
<form onSubmit={this.handlesub}>
<div>
<label>留言内容</label>
<input type='text' placeholder='请输入内容' value={this.state.value} onChange={(event)=>{this.setState({value:event.target.value})}} />
<button type='submit'>留言</button>
</div>
</form>
)
}
}
export default CommentBox2
import React from 'react'
//非受控组件
class CommentBox2 extends React.Component{
constructor(props){
super(props)
this.handlesub=this.handlesub.bind(this)
}
handlesub(ev){
alert(this.textinput.value)
ev.preventDefault()
}
render() {
return(
<form onSubmit={this.handlesub}>
<div>
<label>留言内容</label>
<input type='text' placeholder='请输入内容' ref={(textinput)=>{this.textinput=textinput}} />
<button type='submit'>留言</button>
</div>
</form>
)
}
}
export default CommentBox2
App.js
import logo from './logo.svg';
import './App.css';
import React,{Component} from 'react'
import CommentList from './component/LiuYanBen/CommentList'
import CommentBox from './component/CommentBox'
class App extends Component {
constructor(props){
super(props)
this.state={
comments:['this is my first reply']
}
this.onAddComment=this.onAddComment.bind(this)
}
onAddComment(comment){
this.setState({
comments:[...this.state.comments,comment]
})
}
render() {
const {comments}=this.state
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo"/>
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a className="App-link" href="https://reactjs.org" target="_blank" rel="noopener noreferrer"></a>
</header>
<CommentList comments={comments}/>
<CommentBox commentsLength={comments.length} onAddComment={this.onAddComment} />
</div>
);
}
}
export default App;
CommentList.js
import React from 'react'
const CommentList=({comments})=>{
return(
<div>
<label>评论列表</label>
<ul>
{comments.map((comment,index)=>
<li key={index}> {comment}</li>)}
</ul>
</div>
)
}
export default CommentList
CommentBox.js
import React from 'react'
class CommentBox extends React.Component{
constructor(props){
super(props)
this.handlesub=this.handlesub.bind(this)
this.state={
commentsLength:this.props.commentsLength
}
}
handlesub(ev){
this.props.onAddComment(this.textinput.value)
ev.preventDefault()
}
render() {
return(
<form onSubmit={this.handlesub}>
<div>
<label>留言内容</label>
<input type='text' placeholder='请输入内容' ref={(textinput)=>{this.textinput=textinput}} />
<button type='submit'>留言</button>
</div>
<p>已有{this.state.commentsLength}条评论</p>
</form>
)
}
}
export default CommentBox
AppButton.js
import React,{Component} from 'react'
import ThemeContext from'../../theme-context'
import ThemedBar from './ThemedBar'
const themer={
light:{
background:"blue",
color:"red"
},
dark:{
background:"black",
color:"yellow"
}
}
class AppButton extends Component{
constructor(props){
super(props)
this.state={
theme:'light'
}
this.changeTheme=this.changeTheme.bind(this)
}
changeTheme(themer){
this.setState({
theme:themer
})
}
render() {
return(
<ThemeContext.Provider value={themer[this.state.theme]}>
<div>
<button onClick={()=>{this.changeTheme("light")}}>浅色主题</button>
<button onClick={()=>{this.changeTheme("dark")}}>深色主题</button>
<ThemedBar/>
</div>
</ThemeContext.Provider>
)
}
}
export default AppButton
ThemedBar.js
import React from 'react'
import ThemeContext from '../../theme-context'
const ThemedBar =()=>{
return(
<ThemeContext.Consumer>
{
theme=>{
return(
<div style={{backgroundColor:theme.background,color:theme.color}}>
样式区域
<button color={theme.color}>样式按钮</button>
</div>
)
}
}
</ThemeContext.Consumer>
)
}
export default ThemedBar
ThemeContext.js
import React from 'react'
const ThemeContext=React.createContext()
export default ThemeContext