上一篇說了cli環(huán)境安裝這篇說組件傳值 此文參考
state 和 props 主要的區(qū)別在于 props 是不可變的衅鹿,而 state 可以根據(jù)與用戶交互來改變愕够。這就是為什么有些容器組件需要定義 state 來更新和修改數(shù)據(jù)。 而子組件只能通過 props 來傳遞數(shù)據(jù)浪讳。
如果按照之前的文章來看的應(yīng)該是這個樣子
關(guān)于React的一個重大交易是它如何處理數(shù)據(jù)缰盏,它使用
屬性(稱為props)
和state
來實現(xiàn);
-
父子組件傳值 (Props)
我們將tb數(shù)據(jù) 組成數(shù)組對象由父組件=>App.js傳遞到Table.js ,現(xiàn)在我們將Table.js整理下
//App.js
//必須在App內(nèi)部創(chuàng)建這個數(shù)組 "render()"
render(){
const characters = [
{
name: 'Charlie',
job: 'Janitor',
},
{
name: 'Mac',
job: 'Bouncer',
},
{
name: 'Dee',
job: 'Aspring actress',
},
{
name: 'Dennis',
job: 'Bartender',
},
]
return(
<div className="container">
<Table characterData={ characters } />
<Time />
</div>
)
}
//Table.js:
//提取組件 將table組件提取成 Header Body兩個小組件
const TableHeader = () => {
return (
<thead>
<tr>
<th>Name</th>
<th>Job</th>
</tr>
</thead>
)
}
const TableBody = props=> {
const rows=props.characterData.map((item,i)=>{ // 映射
return (
<tr key={i}>
<td>{item.name}</td>
<td>{item.job}</td>
</tr>
)
})
return <tbody>{rows}</tbody>
}
class Table extends Component {
// 類組件必須包含render()淹遵,并且return只能返回一個父元素口猜。
render() {
const { characterData}=this.props // 父組件傳遞的值
return (
<table>
<TableHeader/>
<TableBody characterData={characterData} />
</table>
)
// 如果return包含在一行中,則不需要括號透揣。
}
}
tips:數(shù)組對象需要在App組件里建立
JavaScript Map es6 此時應(yīng)該跟上篇顯示效果是一樣的
-
現(xiàn)在我們來實現(xiàn)一個時鐘顯示的功能小組件:
每秒更新一次
-
思路:
顯示初始值
=>構(gòu)造函數(shù)
=>每隔1s執(zhí)行一次并渲染到ui
定義一個Time組件方便之后使用 (組件命名規(guī)則首字母大寫济炎,屬性:小駝峰)
//App.js:
const Time=()=>{
return <h3>{new Date().toLocaleTimeString()}</h3>
}
//App組件內(nèi)部
<div className="container">
<Table characterData={ characters } removeCharacter={this.removeCharacter} />
<Time />
</div>
-
toLocaleTimeString
:可根據(jù)本地時間把 Date 對象的時間部分轉(zhuǎn)換為字符串,并返回結(jié)果辐真。 - React 非常靈活须尚,但它也有一個嚴格的規(guī)則:
所有 React 組件都必須像純函數(shù)一樣保護它們的 props 不被更改。
這時候我們使用state
,在不違反上述規(guī)則的情況下侍咱,state 允許 React 組件隨用戶操作耐床、網(wǎng)絡(luò)響應(yīng)或者其他變化而動態(tài)更改輸出內(nèi)容。
// 將Time修改
class Time extends Component{
constructor(props) { //構(gòu)造函數(shù) 將props 傳遞到父類的構(gòu)造函數(shù)中
super(props);
this.state={time:new Date()} // 給state賦值
}
render(){
return <h3>{this.state.time.toLocaleTimeString()}</h3>
}
}
-
constructor
:是一種用于創(chuàng)建和初始化創(chuàng)建的對象的特殊方法 查看具體請點擊 - 現(xiàn)在需要在組件掛載時開始每秒渲染 實現(xiàn) 時鐘楔脯。這就需要使用到 生命周期:
componentDidMount(掛載) , componentWillUnmount(卸載)
componentDidMount() { // 掛載
this.TimeId=setInterval(()=>{
this.tick()
},1000);// 每秒執(zhí)行一次
}
componentWillUnmount() { // 卸載
clearInterval(this.timerID); //清除
}
tick() { // 賦值time
this.setState({
time: new Date()
});
}
全部代碼:
class Time extends Component{
constructor(props) { //構(gòu)造函數(shù)
super(props);
this.state={time:new Date()}
}
componentDidMount() { // 掛載
this.TimeId=setInterval(()=>{
this.tick()
},1000);// 每秒執(zhí)行一次
}
componentWillUnmount() { // 卸載
clearInterval(this.timerID); //清除
}
tick() { // 賦值time
this.setState({
time: new Date()
});
}
render(){
return <h3>{this.state.time.toLocaleTimeString()}</h3>
}
}
//App 組件的 return部分
return(
<div className="container">
<Table characterData={ characters }/>
<Time />
</div>
)
對表格行進行操作 也就是上面顯示的 Delete按鈕的圖片
- 首先將樣子搭出來 修改下 Table.js 中
header
及body
組件
//TableHeader
<thead>
<tr>
<th>Name</th>
<th>Job</th>
<th>Remove</th> // 添加標題
</tr>
</thead>
// TableBody 添加一個button按鈕 觸發(fā)刪除事件 事件由 父組件傳遞過來
<tr key={i}>
<td>{item.name}</td>
<td>{item.job}</td>
<td>
<button onClick={()=>{props.removeCharacter(i)}}>Delete</button>
</td>
</tr>
// table
<TableBody characterData={characterData} removeCharacter={removeCharacter}/>
tips: 為每個表行添加了一個鍵索引,有助于識別每個列表項撩轰。該onClick函數(shù)必須通過一個返回該removeCharacter()方法的函數(shù),否則它將嘗試自動運行昧廷。
- 現(xiàn)在顯示沒問題了 開始做數(shù)據(jù)處理
將characters
存在state里:
state = {
characters:[
{
name: 'Charlie',
job: 'Janitor',
},
{
name: 'Mac',
job: 'Bouncer',
},
{
name: 'Dee',
job: 'Aspring actress',
},
{
name: 'Dennis',
job: 'Bartender',
},
],
}
刪除數(shù)組項:removeCharacter
App類上創(chuàng)建一個方法:
// 刪除 某個數(shù)據(jù)
removeCharacter = index => {
const { characters } = this.state // 讀取當前的數(shù)據(jù)
this.setState({
characters: characters.filter((character, i) => {
return i !== index // 對數(shù)組篩選 并返回符合項
}),
})
}
tips:filter不改變原數(shù)組而是創(chuàng)建一個新數(shù)組堪嫂,并且是在JavaScript中修改數(shù)組的首選方法。這個特殊的方法是測試一個索引與數(shù)組中的所有索引麸粮,并返回除了傳遞的所有索引之外的所有索引
Filter 鏈接溉苛;在App render 時不要忘記 提取數(shù)據(jù) const { characters} = this.state
在render(){}
添加。
全部代碼 包含之前的
//App.js:
import React,{Component} from 'react';
import Table from './Table';
class Time extends Component{
constructor(props) { //構(gòu)造函數(shù)
super(props);
this.state={time:new Date()}
}
componentDidMount() { // 掛載
this.TimeId=setInterval(()=>{
this.tick()
},1000);// 每秒執(zhí)行一次
}
componentWillUnmount() { // 卸載
clearInterval(this.timerID); //清除
}
tick() { // 賦值time
this.setState({
time: new Date()
});
}
render(){
return <h3>{this.state.time.toLocaleTimeString()}</h3>
}
}
class App extends Component{
// state
state = {
characters:[
{
name: 'Charlie',
job: 'Janitor',
},
{
name: 'Mac',
job: 'Bouncer',
},
{
name: 'Dee',
job: 'Aspring actress',
},
{
name: 'Dennis',
job: 'Bartender',
},
],
}
// 刪除 某個數(shù)據(jù)
removeCharacter = index => {
const { characters } = this.state
this.setState({
characters: characters.filter((character, i) => {
return i !== index
}),
})
}
render(){
const { characters} = this.state
// const characters = [
// {
// name: 'Charlie',
// job: 'Janitor',
// },
// {
// name: 'Mac',
// job: 'Bouncer',
// },
// {
// name: 'Dee',
// job: 'Aspring actress',
// },
// {
// name: 'Dennis',
// job: 'Bartender',
// },
// ]
return(
<div className="container">
<Table characterData={ characters } removeCharacter={this.removeCharacter} />
<Time />
</div>
)
}
}
export default App
//Table.js
import React, { Component } from 'react'
const TableHeader = () => {
return (
<thead>
<tr>
<th>Name</th>
<th>Job</th>
<th>Remove</th>
</tr>
</thead>
)
}
const TableBody = props=> {
const rows=props.characterData.map((item,i)=>{
return (
<tr key={i}>
<td>{item.name}</td>
<td>{item.job}</td>
<td>
<button onClick={()=>{props.removeCharacter(i)}}>Delete</button>
</td>
</tr>
)
})
return <tbody>{rows}</tbody>
}
// [[1, 2], [3, 4]].map(([a, b]) =>{
// console.log(a)
// console.log(b)
// return a + b
// });
class Table extends Component {
// 類組件必須包含render()弄诲,并且return只能返回一個父元素愚战。
render() {
const { characterData , removeCharacter}=this.props
return (
<table>
<TableHeader/>
<TableBody characterData={characterData} removeCharacter={removeCharacter}/>
</table>
)
// 如果return包含在一行中,則不需要括號齐遵。
}
}
export default Table
如果中間執(zhí)行有問題的話 多看看 代碼 整理下寂玲,不是很難。也可以跟我聯(lián)系溝通