Day57 (React)

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.");
        };

https://ithelp.ithome.com.tw/upload/images/20210829/20137684If7cfku5XG.jpg


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会错误)前有范例


<<:  安装 Zorin OS 16 Core 与呒虾米

>>:  Mikrotik RouterOS从入门到实战系列-Mikrotik入门第七课

每个人都该学的30个Python技巧|技巧 6:各种运算子(下)(字幕、衬乐、练习)

昨天认识了Python三种运算子中,分别是算术运算子、比较运算子以及逻辑运算子,你还记得分别是哪些吗...

第二十六天:UI切版 & 元件-图文资讯元件、ICON字型 & SVG、通知讯息元件

今天的内容 一、图文资讯元件 二、ICON: Webfont & SVG 三、通知讯息元件 ...

乔叔教 Elastic - 30 - Elasticsearch 的优化技巧 (4/4) - Shard 的最佳化管理

Elasticsearch 的优化技巧 系列文章索引 (1/4) - Indexing 索引效能优化...

[第二十七天]从0开始的UnityAR手机游戏开发-虚拟摇杆 Joystick 01

点击Window→Asset Store开启Unity资产商店 在Asset Store的搜寻列搜寻...

[Day22] 使用官方提供的工具,吸引用户不断回来使用Action

现在,你有个能针对不同装置进行适当对白的Action了。 但要评量一个Action是否成功,用户的...