浅谈 React
React 是一个用于构建用户界面的 JAVASCRIPT 库。用于构建UI,很多人认为 React 是 MVC 中的 V;拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。开源来自Facebook;
介绍前react新朋友会有顾虑,现在国内VUE这么流行,react应不应该学习,在这里我想说,那是必须要学习的,react最接近原生的框架,扩展性强,易上手,有好的社区(出现问题好解决)最重要也多个技能,提升下自己的实力
话不多说现在开始我理解的react吧
React 初体验
安装:react
npm i -g create-react-app
创建项目
create-react-app <项目名称> 或 npx create-react-app <项目名称>
<div id="div"></div>
//react需要挂载的dom元素 可以添加多个
// reacder+JSX
let header = <header id="header"> //JSX语法
<h1>这是标题</h1>
<p>这是副标题</p>
</header>
ReactDOM.render(
"Hello React",
document.querySelector("#div")
);
/*
JSX 是一个基于 JavaScript + XML 的一个扩展语法
- 可以获取值/可以类似比HTML/添加js表达式
- 注意点 : html中class 要写成 className style 内嵌需要写成{{width:100px}}
- 注释: {//}
*/
组件
// 类组件 继承自React.Component 类组件必须有一个render方法
import React,{Component} from "react";
class App extends Component {
constructor(...args){
super(...args); // 小技巧:继承父类的所有方法属性,包括props;建议这种写法
this.state = {
count:1
};
this.handlerClick = this.handlerClick.bind(this);
}
render(){
let {count} = this.state
return <div>
<p>{count}</p>
</div>
}
}
// 函数组件 注意proos传值,return必须添加写
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="Runoob"/>;
ReactDOM.render(
element,
document.getElementById('example')
);
组件通信
/*
props 和 state
参数——props 只读、从外面传进来
状态——state 可变、内部加的
setState(updater, [callback]) 修改state
*/
this.setState(function(){
count++; //修改
return {
count //传出去
}
},()=>{
console.log("组件更新完成"); //修改后的操作
})
/*
组件之间进行信息传递:
父传子:
父组件调用子组件时把数据添加子组件的属性中,然后子组件中从props属性中,获取父级传递过来的数据
子传父:
在父级中定义相关的数据操作方法(或其他回调), 把该方法传递给子级,在子级中调用该方法父级传递消息
兄传弟:
*/
// 父组件
class App extends Component {
state={
name:"kkb"
}
setName=(newName)=>{
this.setState({
name: newName
})
}
render(){
let {name} = this.state;
return <div>
<Child
name = {name} //传子
setName = {this.setName} //子传父
/>
</div>
}
}
export default App;
// 子组件
import React,{ Component } from "react";
class Child extends Component {
state={
count: 1
}
render(){
let {count} = this.state;
let {name,setName} = this.props; // 接收父亲传来的数据跟需要传给父亲的函数
return <div>
<p>name:{name}</p>
<p>count:{count}</p>
<button onClick={()=>{
this.setState(function(){
count++;
return {
count
}
})
}}>递增</button>
<button onClick={()=>{
setName("苏逸尘");
}}>中文名</button>
</div>
}
}
export default Child;
/*
常用 hooks(钩子函数):
- useState
`const [state, setState] = useState(initialState);`
- state 获取值
- setState 设置的操作函数
- useEffect (副作用 hook)
useEffect(()=>{
//副作用函数
return ()=>{
// 副作用函数的返还函数
}
},[依赖参数])
依赖参数: 监听对应参数修改时,或组件挂载时执行
- 当不写依赖参数时,只要组件更新就会执行 副作用函数
- 当 依赖参数为[] 时,副作用函数只在挂载完之后执行
*/
React Router
安装:
$ npm install --save react-router
路由:根据不同的url规则,给用户展示不同的视图(页面)
主要的路由方式:
hash 的路由 #
History API 的路由 / (常用)
使用:
在App.js中添加
<BrowserRouter>
<App />
</BrowserRouter>,
// 比如做个导航
/* nav.js
<Link to="/">首页</Link>
<span> | </span>
<Link to="/about">关于</Link>
<a href="https://www.baidu.com">百度</a> 路由没有跳转的所以需要直接写
<NavLink to="/"
exact
activeClassName="link"
activeStyle={{
fontWeight: "bold"
}}
isActive={()=>{
return true;
}}
>首页</NavLink>
// NavLink 在 Link 基础上添加了 选中当前项的效果
// exact *模糊匹配*
// activeClassName 当前class,默认为 active
// activeStyle 设置style
// isActive 是否选中 返回值为 true 选中当前,否则不选中
*/
// app.js
<Nav />
<Switch>
<Route
path={["/","/home"]} //
exact //精确匹配 path: /join, /join|/join/)
component={IndexView} //不能传递props
/>
<Route
path="/about"
render={() => <Home items={this.state.items} />} //render 可以传递值
/>
<Route
component={View404} //都打开不开或者不存在给个404
// <Redirect to="/" // 路由重定向
/>
</Switch>
常用的路由的操作方法
history:
go(n) 前进后退n
goBack() 返回
goForward() 前进
push(url,state) 在不刷新的情况下跳转 url
length 页面跳转了几次length
location:
hash: "" 当前url中的hash值
pathname: "/join" 当前的url
search: "" 当前 url 的 search 值
state: push 方法传递过来的数据
*重点* match: 当前路由的匹配信息
isExact: true 是否精确匹配
params: {} 动态路由传递的参数 // parpos.match.params来获取动态路由具体的值
path: "" 当前 Route path 属性
url: "" 当前 url 中被匹配成功的一段
hook 函数 减少了多层级props传值
let history = useHistory();
let parmas = useParams();
let loaction = useLocation();
let match = useRouteMatch();
redux \ react-redux \ redux-thunk
- Redux 是一个独立的 JavaScript 状态管理库
- https://www.redux.org.cn/
- 安装 :npm i redux or yarn add redux
使用三部曲:
// 1/定义reducer函数
function reducer(state={
count: 1
},action) {
switch (action.type) {
case "ADD":
return {
count: state.count + 1
}
case "MINUS":
return {
count: state.count - 1
}
}
return state;
}
// 2/ 声明store
const store = createStore(reducer);
const unSubscribe = store.subscribe(()=>{ // 监听数据变化 实时更新不设置据不会自动更新
render();
});
// 3/调用
function render() {
ReactDOM.render(
<div>
<p>{store.getState().count}</p>
<button onClick={()=>{
store.dispatch({ 修改
type: "ADD"
})
}}>递增</button>
<button onClick={()=>{
store.dispatch({
type: "MINUS" //必填 dispatch 修改 state,调用 dispatch 时,store 会调用 reducer 函数,并将 state,和 dispatch 传入的 action,传递 reducer,在 reducer 中,监听 action.type 的不同,来返回新的 state
})
}}>递减</button>
<button onClick={()=>{
unSubscribe();
}}>取消监听</button>
</div>,
document.querySelector("#root")
)
}
react-redux
安装:npm i react-redux
使用必须在index.js中添加
<Provider store={store}> //在 Provider 中有一个 store 属性,store 属性中传入的是 redux 的 store
<App />
</Provider>,
react-redux 的hook
/* react-redux
- useDispatch 操作 dispatch
- useStore 操作store
- useSelector 操作 state
任意位置调用可以大大减少传值的麻烦就是版本有限制
*/
function App() {
const count = useSelector(state=>state.count);
const dispatch = useDispatch();
//console.log(useStore());
return <div>
<p>{count}</p>
<button onClick={()=>{
dispatch({
type: "ADD"
})
}}>递增</button>
</div>
}
初体验Ant Design
安装 npm install antd
- 引入
import { DatePicker } from 'antd';
import 'antd/dist/antd.css';
修改主题
npm i @craco/craco or yarn add @craco/craco //craco (一个对 create-react-app 进行自定义配置的社区解决方案)
- 修改 package.json
"scripts": {
- "start": "react-scripts start",
- "build": "react-scripts build",
- "test": "react-scripts test",
+ "start": "craco start",
+ "build": "craco build",
+ "test": "craco test",
}
- 创建一个 craco.config.js 用于修改默认配置
```
/* craco.config.js */
module.exports = {
// ...
};
```
- 安装 $ yarn add craco-less
- 修改 craco.config.js 配置
```
const CracoLessPlugin = require('craco-less');
module.exports = {
plugins: [
{
plugin: CracoLessPlugin,
options: {
lessLoaderOptions: {
lessOptions: {
modifyVars: { '@primary-color': '#1DA57A' },
javascriptEnabled: true,
},
},
},
},
],
};
总结
react上手快,只要有扎实的js基础,就很容易砌墙,重点在理解react的相关函数,还有就是Redux的使用,最接近原生的js
以模块化的思路去使用它,那将就事半功倍;
中间可能会遇到很多的坑,比如class应该写成className a标签必须带有href,否则就是有难看的提示等等,bug不是问题,问题是要放平心态去解决问题
好了react 还有很长的要走,一起前行吧