关于前端:通过vue学习react四-watchcomputedslot等功能

50次阅读

共计 3501 个字符,预计需要花费 9 分钟才能阅读完成。

这些性能都比较简单些, 通过 react hooks 和 react class 都进行了实现

喜爱就点赞呗

react 实现 watch

react hook 实现 watch

function useWatch<T>(deps: T, handler: (next: T, prev: T) => void, immediate = false) {let nextRef = useRef<T>();
  const isImmediate = useRef(true);

  useEffect(() => {if (isImmediate.current) {handler(nextRef.current as T, deps);
    } else {isImmediate.current = true;}
    return () => {nextRef.current = deps;};
  }, [deps]);
}
# 应用
let [count, setCount] = useState(0);
useWatch(count, (next: typeof count, prev: typeof count) => {console.log(next, prev);
});

react 类写法 实现 watch

class Watch extends React.Component {state = { count: 0};
  constructor(props: FC) {super(props);
  }
  setCount() {
    this.setState({count: this.state.count + 1,});
  }

  componentDidUpdate(_prev: any, prevState: typeof this.state) {console.log(prevState.count, this.state.count);
  }

  render() {
    return (
      <div>
        <button onClick={this.setCount.bind(this)}> 按钮 </button>
      </div>
    );
  }
}

react 实现 插槽 (slot)

react hooks 版本

function Child({children}: {children: React.ReactNode}) {
  return (
    <div>
      child
      {children}
    </div>
  );
}

export default function Slot() {
  return (
    <div>
      <Child>
        <p>2333</p>
      </Child>
    </div>
  );
}

react 类写法

class Child extends React.Component {render() {const { children} = this.props;
    return (
      <div>
        child
        {children}
      </div>
    );
  }
}

class Name extends React.Component {constructor(props: React.FC) {super(props);
  }

  render() {
    return (
      <Child>
        <p>2333</p>
      </Child>
    );
  }
}

react 实现 computed

react hooks 版本

通过 useMemo 模仿即可

export default function Computed() {let [count, setCount] = useState(0);
  const getCount = useMemo(() => {return count * 2;}, [count]);
  return (
    <div>
      {getCount}
      <button
        onClick={() => {setCount(count + 1);
        }}> 按钮
      </button>
    </div>
  );
}

react 类写法

原理则是每次 setState 都会触发 render, 而后从新获取 newCount

class Name extends React.Component {state = { count: 0};
  constructor(props: React.FC) {super(props);
  }
  get newCount() {return this.state.count + 1;}

  render() {
    return (
      <div>
        <p>{this.newCount}</p>
      </div>
    );
  }
}

react 实现 v-model

react hooks 版本

interface formProps {
  name?: string;
  age?: string;
}

export default function Model() {const [form, setForm] = useState<formProps>({});
  const handleChange = useCallback((e: ChangeEvent<HTMLInputElement>, key) => {setForm((raw) => ({...raw, [key]: e.target.value }));
  }, []);
  function onClick() {console.log(form);
  }
  return (
    <div>
      <input type="text" value={form.name ?? ""} onChange={(e) => handleChange(e,"name")} />
      <input type="text" value={form.age ?? ""} onChange={(e) => handleChange(e,"age")} />
      <button onClick={onClick}> 按钮 </button>
    </div>
  );
}

react 类写法

interface formProps {
  name?: string;
  age?: string;
}
class Model extends React.Component<unknown, {form: formProps}> {constructor(props: React.FC) {super(props);
    this.state = {form: {} };
  }
  handleChange(e: React.ChangeEvent<HTMLInputElement>, key: string) {
    this.setState({form: { ...this.state.form, [key]: e.target.value },
    });
  }

  onClick = () => {console.log(this.state.form);
  };

  render() {const { form} = this.state;
    return (
      <div>
        <input type="text" value={form.name ?? ""} onChange={(e) => this.handleChange(e,"name")} />
        <input type="text" value={form.age ?? ""} onChange={(e) => this.handleChange(e,"age")} />
        <button onClick={this.onClick}> 按钮 </button>
      </div>
    );
  }
}

react 实现 css scoped

css module

# index.module.css
.app {
  color: aqua;
  flex: 1;
}
# Css.tsx
import Style from "./index.module.css";
export default function Css() {
  return (
    <div>
      <p className={Style.app}> 我是一个字段 </p>
    </div>
  );
}

css in js (emotion)

装置

npm i @emotion/styled @emotion/react  

应用

/* @jsxImportSource @emotion/react */
import styled from "@emotion/styled";
import {css} from "@emotion/react";
import Style from "./index.module.css";
const base = css`
  color: #ee298c;
`;
const Container = styled.div`
  padding: 23px;
  &:hover {color: ${(props) => props.color};
  }
`;
export default function Css() {
  return (
    <Container color="blue">
      <p className={Style.app}> 我是一个字段 </p>
      <p
        css={css`
          ${base};
          background-color: #eee;
        `}
      >
        test
      </p>
      <p className="test">23333</p>
    </Container>
  );

正文完
 0