React useState, useEffect

写个简单的例子来说明如何使用useState和useEffect。用了boostrap的样式来减少样式的编写,将就看吧。

如何使用bootstrap:
1) 安装:
>npm install -g bootstrap
2) 依赖:
"dependencies": {
    ...
    "bootstrap": "^5.1.3"
  },
3) 引用:
import 'bootstrap/dist/css/bootstrap.css'

代码说明:
1. 启动后加载页面,根据菜单显示不同的内容,这里在App.js中使用了Hook useState来切换菜单加载不同的组件。 当setBody(1)时加载的是Home,setBody(2)时加载Count,setBody(3)时加载Todo。
2. Home组件比较简单,只传了一个变量subject展示在页面上。
3. Count组件使用了两个Hook: useState和useEffect
useState()方法里面唯一的参数就是初始 state, 返回值为:当前 state 以及更新 state 的函数。 https://react.docschina.org/docs/hooks-state.html
可以把 useEffect Hook 看做 componentDidMount,componentDidUpdate 和 componentWillUnmount 这三个函数的组合。useEffect 可以在组件渲染后实现各种不同的副作用。 https://react.docschina.org/docs/hooks-effect.html
4. Todo组件用来实现todo list的管理,通过使用useState根据变化渲染组件。

效果图如下:

 

 

代码如下:

index.js  --传两个参数给App,subject和todoList:

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';
import 'bootstrap/dist/css/bootstrap.css'

const root = ReactDOM.createRoot(document.getElementById('root'));
const todoList = [{'name': 'task1', 'completed': true},
    {'name': 'task2', 'completed': false},
    {'name': 'task3', 'completed': false}
];

root.render(
    <React.StrictMode>
        <App subject="Tina!" todoList={todoList}/>
    </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js  --切换菜单,加载不同的component

import React, {useState} from 'react';
import Home from './components/home/Home'
import Count from './components/count/Count'
import Todo from './components/todo/Todo'

function App(props) {
    const [body, setBody] = useState(1);

    return (
        <>
        <div className="navbar navbar-expand-lg navbar-static-top">
            <a className="navbar-brand" href="#">React Exercise</a>
            <div className="collapse navbar-collapse">
                <ul className="nav navbar-nav">
                    <li className="nav-item active">
                        <a className="nav-link" href="#" onClick={() => setBody(1)}>Home</a>
                    </li>
                    <li className="nav-item active">
                        <a className="nav-link" href="#" onClick={() => setBody(2)}>Count</a>
                    </li>
                    <li className="nav-item active">
                        <a className="nav-link" href="#" onClick={() => setBody(3)}>Todo</a>
                    </li>
                </ul>
            </div>
        </div>
        <div className="text-center">
            {body === 1 ? (
                <Home subject={props.subject}/>
            ) : body === 2 ? (
                <Count />
            ) : body === 3 ? (
                <Todo list={props.todoList}/>
            ) : <br/>}
        </div>
        </>
    );
}

export default App;

Home.js  --显示图片和文字,文字根据subject来展示

import logo from './logo.svg'

function Home({ subject}) {
    return (
        <>
            <h2 className="text-primary">
                Hello, {subject}
            </h2>
            <img src={logo} className="img-thumbnail" alt="logo" />
        </>
    );
}

export default Home;

Count.js  --通过使用useState来记录点击button的次数,使用useEffect来控制浏览器title的显示变化

import React, {useState, useEffect} from 'react';

function Count() {
    const [count, setCount] = useState(0);

    useEffect(() => {
        document.title = `You clicked ${count} times`;
    });

    return (
        <div className="col-lg text-center">
            <p>You clicked {count} times! </p>
            <button className="btn btn-success" onClick={() => setCount(count + 1)}>
                Click me
            </button>
        </div>
    );
}

export default Count;

Todo.js  --根据传入的变量todoList初始化页面,使用useState改变todoList,从而达到重新渲染页面的目的

import React, {useState} from 'react';

function Todo({list}) {
    const [value, setValue] = useState("");
    const [todos, setTodos] = useState(list);

    return (
        <>
            <div>
                <h2>What needs to be done?</h2>
                <div className="input-group m-3">
                    <input type="text" className="form-control" value={value} onChange={e => setValue(e.target.value)} />
                    <div className="input-group-append">
                        <button className="btn btn-outline-secondary" type="button" onClick={e => {
                            e.preventDefault();
                            if (!value) return
                            var todoItem = {'name': value, 'completed': false};
                            setTodos([...todos,todoItem])
                            setValue("")
                        }}> Add</button>
                    </div>
                </div>
            </div>
            <ul className="list-group">
                {todos.map((item, index) =>
                    <li className="list-group-item d-flex justify-content-between align-items-start">
                        <label>
                            {item.name}
                        </label>
                        <button type="button" className="btn btn-outline-danger" onClick={e => {
                            e.preventDefault();
                            todos.splice(index, 1);
                            setTodos([...todos])
                        }}>
                            Delete
                        </button>
                    </li>
                )}
            </ul>
        </>
    );
}

export default Todo;

GitHub - tinazhao1985/react-test

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值