【SolidJs】仅次于原生JS的超级性能!SolidJs框架教程【中】

766 阅读1分钟

Props

Children

在SolidJs中,如果在组件中写一些children,并非仅仅作为展示,而需要在子组件中处理children时,需要用到children函数。

举个🌰

main.tsx

import { render } from "solid-js/web";
import { createSignal, For } from "solid-js";

import ColoredList from "./colored-list";

function App() {
  const [color, setColor] = createSignal("red");
  const [persons] = createSignal(["Alice", "Bob", "Jack"])

  return <>
    <ColoredList color={color()}>
      <For each={persons()}>{item => <div style={{color: color()}}>{item}</div>}</For>
    </ColoredList>
    <button onClick={() => setColor("green")}>Set Color</button>
  </>;
}

render(() => <App />, document.getElementById('app'));

color-list.tsx

import { createEffect, children } from 'solid-js'
export default function ColorList(props) {
    const c = children(() => props.children) // 处理children
    createEffect(() => c().forEach(item => item.style.color = props.color)) // 监听props.color并修改children的颜色
    return <>{c()}</>
}

Store

创建Store

import { render } from "solid-js/web";
import { createStore } from "solid-js/store";

const App = () => {
  const [store, setStore] = createStore({ username: "Alice" });
  console.log("store -----> ", store); // "store -----> " {"username": "Alice"}
  const toggleUsername = (username) => {
    console.log(username);
    setStore("username", (name) => {
      console.log("store.name ----->", name); // "store.name ----->" "Alice"
      return username;
    });
  };
  return (
    <>
      <div>{store.username}</div>
      <button onClick={[toggleUsername, "bob"]}>setStore username</button>
    </>
  );
};

render(App, document.getElementById("app"));

修改Store

修改Store有一个修饰符produce,需要吧上面的🌰改成这样修改:

const toggleUsername = (username) => {
    setStore(
        'username',
        produce((name) => username)
    )
}

produce的作用是小范围修改值

它可以让你在 setStore 调用中改变 Store 对象的可写代理版本

Context

Context API 用来传递数据,不依赖Props,多用于组件间的数据共享,食用方法一般为,创建一个Context对象,该对象包含一个用于注入数据的Provider组件,举个计数器的🌰:

main.tsx

import { render } from 'solid-js/web'
import Nested from './nested'
import { CounterProvider } from './counter'

function App() {
    return <>
        <h1>Welcome</h1>
        <Nested />
    </>
}

render(() => {
    <CounterProvider count={1}> <App /> </CounterProvider>,
    document.getElementById('app')
})

nested.tsx

import { useCounter } from './counter.tsx'
const [count, {invrement,decrement}] = useCounter()
export default function Nested() {
    return (
        <>
            <div>0</div>
            <button>+</button>
            <button>-</button>
        </>
    )
}

counter.tsx

import { createSignal, createContext, useContext } from 'solid-js'
const CounterContext = createContext()

export function CounterProvider(props) {
    const [count, setCount] = createSignal(props.count || 0),
          store = [
              count,
              {
                  invrement() { setCount(c => c + 1) },
                  decrement() { setCount(c => c - 1) }
              },
          ]
    return (
        <CounterContext.Provider value={store}>{props.children}</CounterContext.Provider>
    )
}

export function useCounter() { return useCountext(CounterContext)}

懒加载组件

举个🌰

main.tsx

import { render } from "solid-js/web";
import { lazy } from "solid-js";

const Greeting = lazy(() => import("./greeting"))

function App() {
  return (
    <>
      <h1>Welcome</h1>
      <Greeting name="Jake" />
    </>
  );
}

render(() => <App />, document.getElementById("app"));