1.製作元件内增加参数:
(Lab_Event > index_OK.html、index_2.html)
(1)製作元件Toggle增加属性dataList、并更改dataList[0]
class Toggle extends React.Component { constructor(props) { super(props); this.state = { //两个属性isToggleOn、dataList isToggleOn: true, dataList: [ { name: "Jina" }, {}, {}] }; this.state.dataList[0].name = "other peoplo"; //1.此处网页跑完前已变更 }
(2)预告执行程式时alert呼叫 1.data 2.dataList[0].name 3."Button clicked,显示变更setState
doClick = (e, data) => { alert(data); alert(this.state.dataList[0].name); this.setState({ //2.显示变更网页使用后属性 isToggleOn: !this.state.isToggleOn, }); alert("Button clicked."); // this.setState({}); //2.显示变更网页使用后属性 };
(3)render 案到按钮回传
render() { return ( <button // 滑鼠点击事件,data undefined,因为没给值 onClick={this.doClick} // 执行此处 okkk > 1000 > other peoplo > Button clicked // 执行顺序 alert("okkk")后 将值传入(e,data)跑doClick onMouseLeave={(e) => { alert("okkk"); { this.doClick(e, 1000); } }} className="btn btn-outline-success" > {this.state.isToggleOn ? "ON" : "OFF"} </button> ); }
Q:为何dataList[0].name改为"other peoplo"没有setState亦变更显示?
A:因setState作用为网页跑完后,变更属性时显示变更
但此处网页跑完前dataList[0].name已变更完毕
2.(e)必要?
(Lab_Event > index_OK.html)
doClick = (e) => { // console.log(this); this.setState({ isToggleOn: !this.state.isToggleOn, }); };
不必要,仍可执行,但增加可以看React包装过的event事件
但没有e也可用使用event看event事件
doClick = (e) => { console.log(this); //Toggle {props: {…}.... console.log(event); //此event 是传统js 的event事件 console.log(e); //doClick = (e)没有e会无法显示,此e传入的是React 包装过的event事件 this.setState({ isToggleOn: !this.state.isToggleOn, }); alert("Button clicked."); };
3.更改事件
(Lab_Event > index_OK.html)
onMouseLeave
render() { return ( <button onMouseLeave={this.doClick} className="btn btn-outline-success"> {this.state.isToggleOn ? "ON" : "OFF"} </button> ); }
onClick
render() { return ( <button onClick={this.doClick} className="btn btn-outline-success"> {this.state.isToggleOn ? "ON" : "OFF"} </button> ); }
4. JS - ... Spread 展开
(Lab_Event > ClassroomDemo.html、demo.html)
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Operators/Spread_syntax
(1)原本没有使用...时
var dataList = [10, 20, 30]; var newDataList = []; for (let i = 0; i < dataList.length; i++) { var item = dataList[i]; //1.取出一个[0][1][2] newDataList.push(item); //2.放进来 } newDataList.push(40); //3. [3]:40 debug.innerText = newDataList.join(" | "); //10 | 20 | 30 | 40
(2)使用...
var dataList = [10, 20, 30]; //複製dataList[10, 20, 30]的内容 再把他解压缩展开 var newDataList = [...dataList, 40]; debug.innerText = newDataList.join(" | "); //10 | 20 | 30 | 40
两种结果相同,但...较简洁
其他範例
class Toggle extends React.Component { constructor(props) { super(props); this.state = { isToggleOn: true }; } doClick = (e, currentToggle) => { //1.把旧状态Toggle下的state拿出来,成立一个新状态 let newState = { ...this.state }; //2.新状态的属性 newState.isToggleOn = !currentToggle; //3.交给setState 显示改变新状态的属性 this.setState(newState); };
5. Map 将阵列内客依序传入处理,但需retur做回传
(JavaScript > 05_array> Array_20_map.html)
var data = [3, 0, 1, 8, 7, 2, 5, 4, 9, 6]; //map将阵列内客依序传入,但需retur做回传,否则map跑完,dataList的阵内容是空的 var dataList = data.map(function (item) { return item + 10; }); //将阵列内容依序传入 并+10
箭头函式 (只回传一值 => 无须{}及return)
var dataList = data.map((aaa) => aaa + 10); //将阵列内容依序传入 并回传+10
同方法4.,非 => 写法
var dataList = data.map(function (aaa) { return aaa + 10; });
6.Props 一路演进
(Lab_Props > ClassroomDemo_a.html)
(1)製作Welcome元件
class extends React.Component { render() { return <h3>{this.props.name}</h3>; } }
(2)expertList为[] 此次为"资料"
const expertList = [ { id: 1, name: "Jeter0.5" }, { id: 2, name: "Messi0.5" }, { id: 3, name: "Jordan0.5" }, { id: 4, name: "QQQ0.5" }, ];
(3)将expertList[] 做成一个 Welcome元件
const element3 = ( <div> {expertList.map((expert) => ( <Welcome name={expert.name} /> //Welcome元件的expertList显示 ))} <Welcome name="Jeter" /> <Welcome name="Messi" /> <Welcome name="Jordan" /> </div> ); ReactDOM.render(element3, document.getElementById("root"));
(4)合体(2)(3),製作新元件App
注意this.state.expertList必要,才能指定「这里」,否则会抓到外面const expertList[]
并且return element5
class App extends React.Component { constructor() { super(); this.state = { expertList: [ { id: 1, name: "Jeter" }, { id: 2, name: "Messi" }, { id: 3, name: "Jordan" }, ], }; } // 把element4搬进来製作element5 render() { const element5 = ( // this.state.expertList必要,才能指定「这里」,否则会抓到外面const expertList[] <div> {this.state.expertList.map((expert) => ( <Welcome name={expert.name} key={expert.id} /> ))} <Welcome name="Jeter" /> <Welcome name="Messi" /> <Welcome name="Jordan" /> </div> ); // return return element5; } }
(5)变更(4),製作按钮 并 增加按钮事件toUpperCase
class App2 extends React.Component { constructor() { super(); this.state = { expertList: [ { id: 1, name: "Jeter.App2" }, { id: 2, name: "Messi.App2" }, { id: 3, name: "Jordan.App2" }, ], }; } // 3.製作onClick事件 doClick = () => { //新式写法 有改变就变更显示 this.state.expertList[0].name = this.state.expertList[0].name.toUpperCase(); //toUpperCase转大写 this.setState({}); //网页跑完后,变更时显示变更属性 }; render() { // 1. 此处清空,显示搬到return // const element6 = ( // <div> // {this.state.expertList.map((expert) => ( // <Welcome name={expert.name} key={expert.id} /> // ))} // <Welcome name="Jeter.element6" /> // <Welcome name="Messi.element6" /> // <Welcome name="Jordan.element6" /> // </div> // ); //2. return 製作按钮 并 製作onClick事件 return ( <div> <button class="btn btn-success" onClick={this.doClick}> 转成大写的按钮 </button> {this.state.expertList.map((expert) => ( <Welcome name={expert.name} key={expert.id} /> ))} </div> ); } } ReactDOM.render(<App2 />, document.getElementById("root4"));
(6)接续(Lab_Props > ClassroomDemo_c.html)功能同(5)
步骤7开始为变更内容~~~~~~~~~6.前为导读
// 2.App元件state属性放expertList class App extends React.Component { state = { expertList: [ { id: 1, name: "Jeter" }, { id: 2, name: "Messi" }, { id: 3, name: "Jordan" }, ], }; // 3. 製作f,toUpperCase并且可以跑完网页后,属性变更时随时变更setState doClick = (e) => { let newState = { ...this.state }; newState.expertList[0].name = newState.expertList[0].name.toUpperCase(); this.setState(newState); }; // 12.製作删除资料的f // 15.製作成箭头函式 doDelete = (e, id) => { alert("我负责删除资料" + id); alert(e + id); //16.执行删除的f var newState = { ...this.state }; newState.expertList = newState.expertList.filter((expert) => expert.id != id); this.setState(newState); }; // 4.回传网页内容让button绑onClick滑鼠事件执行doClick // 5.内含f,App属性内expertList.map方法,将[]一个一个return製作成Welcome物件(9.12.) render() { return ( <div className="container"> <button className="btn btn-outline-success" onClick={this.doClick}> Jeter toUpperCase </button> {this.state.expertList.map((expert) => ( // 9.key是react才有的,所以多製作id={expert.id} // 12.製作删除资料的属性onDelete={this.doDelete} <Welcome name={expert.name} key={expert.id} id={expert.id} onDelete={this.doDelete} /> ))} </div> // Welcome物件的name = Jeter id=1 ); } } // 6.Welcome回传props属性的name(5.给的) class Welcome extends React.Component { // 8.製作onClick事件内的f handlerDelectButtonClick handlerDelectButtonClick = (e) => { alert(this.props.key); // 10.抓不到react自己创的 所以做一个id alert(this.props.name); alert(this.props.id); // 11.抓到了 this.props.onDelete(); //呼叫alert("我负责删除资料"); > 此处没给值 this.props.onDelete(this.props.id); //13.呼叫alert("我负责删除资料 + id"); > 此处没给值 this.props.onDelete(e, this.props.id); //14.传两个值给onDelete() 并执行; }; render() { // JSX 外面一定要包东西,把每个东西包起来<div> 或使用 <React.Fragment> //return()必要,避免return; return ( // 7.新增<button>及其内onClick事件 <h3> {this.props.name} {" "} <button onClick={this.handlerDelectButtonClick} class="btn btn-outline-danger"> × </button> </h3> ); } } // 1.製做App元件 // 输出到root ReactDOM.render(<App></App>, document.getElementById("root"));
7. JSX 外面一定要包东西,把每个东西包起来
div 或使用 React.Fragment
class Welcome extends React.Component { render() { //return()必要,避免return; return ( //方法1. // <h3>{this.props.name}</h3> //方法2. // <div> // <h3>{this.props.name}</h3>我是想增加的内容 // </div> //方法3. <React.Fragment> <h3>{this.props.name}</h3>我是想增加的内容 </React.Fragment> ); } }
8.useState 设定初值
(Lab_useState > index_0.html)
//1. function元件製作 function App() { // 2.解构赋值 let[变数, 方法] // useState()设定初值count=变数,setCount=方法 ,传回阵列[] let [count, setCount] = React.useState(50); //count=50 const doIncrement = () => { // 4.onClick事件的f alert("OK"); count += 1; // 5. +1 但不会显示 console.log(Date()); console.log(count); console.log(setCount); setCount(count + 1); // 6. +1 setCount似setState显示网页跑完之后的变更 }; return ( // 3.新增buttonu并增加onClick事件 <React.Fragment> <h3>count:{count}</h3> <button onClick={doIncrement} className="btn btn-outline-success"> 一直加上去 </button> </React.Fragment> ); }
连续使用setCount会错误
用=>让程式可以同时进行而加二
const handleIncrement = () => { // 连续使用setCount会错误 // 加一? 还是加二? 加一 解决如下 // setCount(count + 1); // setCount(count + 1); // -------------------- // 加一? 还是加二? 加二 // 用=>让程式可以同时进行而加二 setCount((previous) => previous + 1); setCount((previous) => previous + 1); };
9.解构赋值 : []给[]、{}给{}
(Lab_useState > demo02.html)
[]给[] 需照顺序
var datalist = [10, 20]; // var x = datalist[0]; // var y = datalist[1]; var [x, y] = datalist; //解构赋值 [x, y] = [10, 20] alert(x + " " + y);
{}给{} 需同名资料
var player = { firstName: "Jeremy", LastNasme: "Lin", unmber: 7, }; // 方法1. // var LastNasme = player.LastNasme; // var firstName = player.firstName; // 方法2.使用解构赋值 var { LastNasme, firstName } = player; alert(LastNasme); alert(firstName);
10.useEffect 副作用
变更显示完之后,想做的事件都放在useEffect里面
(Lab_useEffect > index_1_useEffect.html)
// 2.製作App元件 function App() { const [count, setCount] = React.useState(0); //const [count2, setCount2] = React.useState(0); // 4.变更显示count + 1 const doClick = () => { setCount(count + 1); }; // 5.变更显示完之后,想做的事件都放在useEffect里面 React.useEffect(() => { document.title = `Click count: ${count}`; //网页名称变更 }); //}, [count]) return ( // 3.按钮挂上onClick事件,按下按钮触发doClick <div> <button onClick={doClick}>Click count: {count}</button> </div> ); } // 1.render ReactDOM.render(<App />, document.getElementById("root"));
useEffect内的为什么不放在doClick内? ********************************重点
因为怕程式没跑到(连续使用setCount会错误)前有範例