React

在类组件下可通过 React.createRef() 或refs直接获取元素。
使用PropTypes对类型和必要性进行限制,defaultProps设置默认值。
unmountComponentAtNode只对ReactDOM.render挂载在顶层的组件才生效,其余无关render方法永远返回的都是false。
初始化
父组件的constructor-------父组件的componentWillMount-------父组件的render------子组件的constructor--------子组件的componentWillMount-------子组件的render----子组件componentDidMount--------父组件componentDidMount(先初始化渲染父组件然后渲染挂载子组件,最后挂载父组件,当组件销毁时先销毁父组件再销毁子组件)
setState更新
setState-------父组件的shouldCompnentUpdate------父组件的componentWillUpdate-------子组件的componentWillUpdate—父组件的componentDidUpdate(父组件更新之后也会先更新子组件,待子组件更新完毕后再触发父组件的更新完毕钩子)
forceUpdate更新
forceUpdate绕过shouldCompnentUpdate走更新流程
vue和react更新的不同,vue的父组件更新时只有当页面上有相关数据的更新才会去触发update函数,子组件也是一样,而react则是只要更新了数据,不管数据是否存在页面上,都会触发update更新函数。
href的链接如果是./xxxx或xxx的形式则是替换当前路径,如果是/xxx则替换所有路径
路由传参

风格一
声明式
传递
<Link to="/Home/Home/1">Home1</Link>
匹配
<Route path="/Home/Home1/:id" component={Home1}></Route>
接收
props.match.params.id

风格二
声明式
传递
<Link to="/Home/Home1?id=1">Home1</Link>
无须匹配
<Route path="/Home/Home1" component={Home1}></Route>
接收
通过qs库解析
function Home1(props) {
  return <div>{qs.parse(props.location.search.slice(1)).id}</div>;
}
风格三 传state
声明式
<Link to={{ pathname: "/Home/Home2", state: { id: 2 } }}>Home22</Link>
无须匹配
<Route path="/Home/Home2" component={Home2}></Route>
通过state接收
function Home2(props) {
  console.log(props.location.state);
  return <div>{props.location.state.id}</div>;
}
如果是编程式导航则直接调用props里的history里的push与replace方法。
只有state种传参在打开新页面会为undifine所以要注意空处理,其他两种形式,只要路由保证格式一致,组件就会自动封装数据。

可以使用withRouter让一般组件可以使用history

在线切换主题
1.使用css变量

// 定义变量
:root {
      --main-bg-color: red;
}
// 使用变量
.box {
      width: 100px;
      height: 100px;
      background-color: var(--main-bg-color);
}
// 修改变量
document.getElementsByTagName("html")[0].style.setProperty("--main-bg-color", "yellow");

Redux
redux包含store,action,reducer

// 同步action
export var createIncrement = (data) => ({ type: Increment, data });
// 异步action,如果不想在组件内做异步操作,可以开启异步action
export var createAsynIncrement = (data, time) => {
  return () => {
    setTimeout(() => {
      store.dispatch(createIncrement(data));
    }, time);
  };
};
// 开启异步action需要引入
import thunk from "redux-thunk";
const store = createStore(countReducer, applyMiddleware(thunk));

componentDidMoun和useEffect被执行两次可以去除<React.StrictMode>

setState在事件函数中是异步的,并且最终会合并,并且取最后一次执行的值,而setState在异步环境中则为同步执行(为什么?如何识别同步异步环境?)。
在函数式组件中的异步环境useState会有问题,如果不使用函数式更新则一直为原值,因为在定时器里根本就没有改原来的state值,而是改了useState里的值,第二次取出来的才是新值。

export default function Funtest() {
  console.log("渲染開始");
  const [state, setstate] = React.useState(0);
  console.log("state", state);
  React.useEffect(() => {
    console.log("useEffect被執行了");
    setInterval(() => {
      console.log("state一直为0");
      setstate(state + 1);
      //   setstate((state) => {
      //     console.log("定時器開始執行", state);
      //     return state + 1;
      //   });
    }, 2000);
  }, []);
  return (
    <div>
      {state}
      <button
        onClick={() => {
          setstate(state + 1);
        }}
      >
        加一
      </button>
    </div>
  );
}

祖孙传值时也可使用Context.provider,记住得用static contextType声明
Purecomponent只是简单的地址对比,如果没有改地址也就不会更新。
当子组件发生错误时,父组件可以使用getDerivedStateFromError,而vue可以使用errorCaptured处理
可以使用Navigate组件实现声明式主动跳转。
react-router6不支持类组件获取路由参数,函数组件可以使用useParams,useSearchParams,useLocation分别获取params,search和state。编程式路由导航则使用useNavigate
babel会把函数,类,jsx语法转译成React.createElement,只不过类型不一样。ReactDOM.render会根据类型去渲染。

React原理

1.通过babel把函数标签,类标签,jsx转化成React.createElement(type, config, children),这里会生成虚拟dom对象,把config全部放置在props上,如果有ref或者key属性,会在props上设置这两个属性的get方法。
普通标签会生成:

{
    $$typeof: Symbol(react.element),
   "type": "span",
    "key": "1",
    "ref": "mySpan",
    "props": {
        "name": "wth",
        "self": "mySelf",
        "source": "mySource",
        "children": "我是span",
        onClick: fn   
         },
    "_owner": null,
    "_store": {}
}

函数标签会生成:

{
    $$typeof: Symbol(react.element),
    "key": null,
    "ref": null,
    "props": {
        "children": [
            {
                "type": "span",
                "key": "1",
                "ref": "mySpan",
                "props": {
                    "name": "wth",
                    "self": "mySelf",
                    "source": "mySource",
                    "children": "我是span"
                },
                "_owner": null,
                "_store": {}
            },
            "2"
        ]
    },
    "_owner": null,
    "_store": {}
}

2.通过ReactDOM.render(element, container, callback) 开始进入render,大致分为3个阶段。

初始化阶段

legacyRenderSubtreeIntoContainer(null, element, container, false, callback)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值