写个简单的例子来说明如何使用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;

被折叠的 条评论
为什么被折叠?



