render () {
if (this.state.isLoading) { // 正在加载中
return <h1>Loading...</h1>
}
return <div>这就是我们想要的内容</div>
}
// 钩子函数 五秒钟之后 修改状态值
componentDidMount () {
setTimeout(() => {
this.setState({
isLoading : false
})
}, 3000);
}
return this.state.isLoading ? (<h1>Loading...</h1>) : (<div>这就是我们想要的内容</div>)
return this.state.isLoading && (<h1>Loading...</h1>)
// 准备数据
state = {
list :['小苹果','大香蕉','黄橙子']
}
return (<ul>
{this.state.list.map(item => {
return <li>{ item }</li>
}) }
</ul>)
// 准备数据
state = {
list2: [{ id: 1, name: '春' }, { id: 2, name: '飞' }, { id: 3, name: '莲' }]
}
// 遍历
return (
<ul>
{this.state.list2.map(item => {
return <li key={item.id}>{ item.name }</li>
}) }
</ul>
)
// render 钩子函数
render () {
return (<ul>
{ this.renderLi() }
</ul>)
}
// 提取到的一个函数
// 必须要有返回值
renderLi () {
return this.state.list2.map(item => {
return <li key={item.id}>{ item.name }</li>
})
}
// 这个{{}} 不是双括号语法, 而是单括号里面有个 样式对象
//{} 可以拿到原始类型
<div style={{ color: 'pink', backgroundColor: 'yellowgreen', height: 300 }}>
//1. 外部 index.css
.red {
color: red;
font-size: 50px;
}
//2. 引入
import './index.css'
//3. 添加类
<p className='red' >哈哈</p>
准备数据 - 列表展示
受控组件
表单头部展示收集数据
补充 : 非受控组件
list: [
{ id : 1, username :'张三', content :'做一个凡人' },
{ id : 2, username :'李四', content :'贪财好色' },
{ id : 3, username :'王五', content :'一身正气' }
],
<ul>
{this.state.list.map(item => {
return (<li key={item.id}>
<p>评论人 : {item.username}p>
<p>评论内容 : {item.content}p>
li>)
}) }
ul>
受控组件模块
<div>
评论的人 :
<input
onChange={e => this.getValues('username', e.target.value)} # +
name="username"
value={username}
style={{ width: '214px' }}
type="text"
/>
<br />
评论内容 :
<textarea
onChange={e => this.getValues('content', e.target.value)} # +
name="content"
value={content}
cols="30"
rows="10"
></textarea>
<button onClick={this.add}>添加评论</button>
</div>
getValues = (name, value) => {
this.setState({
[name]: value
})
}
add = () => {
// 获取数组
const { list, content, username } = this.state
let obj = {
id: +new Date(),
content,
name : username
}
this.setState({
list: [obj, ...list],
content: '',
username :''
})
}
非受控组件模块
导入 : 给 input 添加了一个value ,展示默认值
表单元素 是用来收集数据的
react 表单元素分为 : 受控组件 + 非受控组件
受控组件 : 受 React 控制的组件
如何成为受控组件 ? 给 input 添加value 值, 那么这个input 就成了受控组件
M ==> V , V ==> M (我们自己处理)
- 1.需要给 input 添加 value 并且赋值 => M ==> V
- 2.onChange={ this.handleInput } ==> 监听 V 的数据变化, 收集值赋值给 M
- 3.
handleInput = (e) => {
// 监听input 的变化
// (V) 拿到文本框的值, 修改 state 里面的数据(M)
console.log(e,target.value)
// 修改状态
this.setState({
username : e.target.value
})
}
// 文本输入框
<input onChange={this.handleInput} value={username} type="text" /> <br />
// 文本域
<textarea onChange={this.handleTextarea} value={content} cols="30" rows="10">textarea>
// 下拉框
<select value={city} onChange={this.handleSelect}>
<option value="sh">上海option>
<option value="hz">杭州option>
<option value="bj">北京option>
select>
// 处理 input
handleInput = (e) => {
this.setState({
username: e.target.value
})
}
// 同上
.....
// 让其他表单都绑定到一个事件中
// 文本输入框
<input name='username' onChange={this.handleInput} value={username} type="text" /> <br />
// 文本域
<textarea name='content' onChange={this.handleTextarea} value={content} cols="30" rows="10"></textarea>
// 下拉框
<select name='city' value={city} onChange={this.handleSelect}>
<option value="shanghai">上海</option>
<option value="hangzhou">杭州</option>
<option value="beijing">北京</option>
</select>
handle = e => {
// console.log(e.target.name);
this.setState({
[e.target.name] : e.target.value
})
}
// 文本输入框
<input onChange={(e) => this.getValues('username', e.target.value)} value={username} type="text" /> <br />
// 文本域
<textarea onChange={(e) => this.getValues('content', e.target.value)} value={content} cols="30" rows="10"></textarea>
// 下拉框
<select value={city} onChange={ (e) => this.getValues('city', e.target.value) }>
<option value="shanghai">上海</option>
<option value="hangzhou">杭州</option>
<option value="beijing">北京</option>
</select>
getValues = (name, value) => {
this.setState({
[name] : value
})
}
导入 : 如果不想让inptu 成为受控组件 , 又想添加默认值
####非受控组件介绍:
constructor(){
super()
// 方式1
this.iptRef = React.createRef()
}
// 和 state 一样
// 方式2: 属性初始化语法
iptRef = React.createRef()
<input ref={ this.iptRef } />
// 可以通过尝试点击按钮
click = () => {
console.log(this.iptRef.current.value)
}
// 父组件
class Parent extends React.Component {
// 1. 准备好数据
state = {
pName : '父的数据'
}
render() {
return (
<div>
<p>哈哈</p>
//2. 通过属性 将数据传递给子组件
<Child name={this.state.pName}></Child>
</div>
)
}
}
// 子组件
// 3. 通过 props 获取数据
const Child = (props) => <div>子组件 { props.name }</div>
// 父组件
class Parent extends React.Component {
// 第一步 :父组件准备一个方法
pFn = (data) => {
console.log('调用了',data);
}
render() {
return (
<div>
<p>哈哈</p>
{/* 第二步 : 通过属性将方法产传递给子组件 */}
<Child cfn={ this.pFn } ></Child>
</div>
)
}
}
// 子组件
class Child extends React.Component {
render () {
return (<div>
<button onClick={this.sendMsg}>点击发送</button>
</div>)
}
sendMsg = () => {
// 第三步 : 子组件通过props 拿到这个方法, 并且传参
this.props.cfn('撩汉子')
}
}
组件化
父传子 => 把 list 传给 CommentsList 组件 => 遍历展示列表
子传父 => 把表单里的数据新对象 => 点击添加评论 => 传给 Comments组件
pGetData
添加评论
远房亲戚
的关系,此时,就可以使用 Context 来通讯。// 1. 创建 Context 对象, 并解构出来两个组件
const { Provider, Consumer } = React.createContext() # +
//2. 类组件
class One extends React.Component {
state = {
color :'red'
}
render() {
return (
// 第二步 : 使用 Provider 组件包裹 one组件, 只有被包裹的部分里面才能获取数据
// 通过 value 属性提供要共享的数据
<Provider value={ this.state.color }> # +
<div>
<p> One </p>
<Two></Two>
</div>
</Provider>
)
}
}
class Two extends React.Component {
....
}
class Three extends React.Component {
....
}
class Four extends React.Component {
render() {
return (
<div>
<p>Four</p>
{/* 3.在 Four 组件中, 通过 consumer 来获取数据 */}
{/* 遵循的是 render-props 思想 后面介绍 */}
<Consumer>
{data => {
return <p style={{ color : data }} >这是测试用的</p> # +
}
}
</Consumer>
</div>
)
}
}