SolidJS流程控制(2)

330 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第7天,点击查看活动详情

流程控制-Dynamic

Dynamic标签负责将动态渲染数据,可以将元素的字符串或者组件函数传递给它,并使用提供的其余的props来渲染组件。简单来说是去控制不同组件的切换,类似于Vue中的动态Components

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

const RedThing = () => <strong style="color: red">Red Thing</strong>;
const GreenThing = () => <strong style="color: green">Green Thing</strong>;
const BlueThing = () => <strong style="color: blue">Blue Thing</strong>;

const options = {
  red: RedThing,
  green: GreenThing,
  blue: BlueThing
}

function App() {
  const [selected, setSelected] = createSignal("red");

  return (
    <>
      <select value={selected()} onInput={e => setSelected(e.currentTarget.value)}>
        <For each={Object.keys(options)}>{
          color => <option value={color}>{color}</option>
        }</For>
      </select>
      <Dynamic component={options[selected()]} />
    </>
  );
}

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

该段代码创建一个对象,里面包含上述的函数组件名称,根据select标签去修改响应式数据selected,使用Dynamic动态渲染不同的组件。

流程控制-Portal

有时候我们需要在整个document添加额外的节点。因此solid提供了一个portal组件,该组件可以将子内容插入到对应的位置。默认是在body下面。

import { render, Portal } from "solid-js/web";
import "./styles.css";

function App() {
  return (
    <div class="app-container">
      <p>Just some text inside a div that has a restricted size.</p>
      <Portal>
        <div class="popup">
          <h1>Popup</h1>
          <p>Some text you might need for something or other.</p>
        </div>
      </Portal>
    </div>
  );
}

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

代码中将Portal的内容插入到整个代码结构下,防止被正常文档流的节点截断。

流程控制之ErrorBoundary(错误边界)

有时会因为代码出错导致页面不能正常渲染,而ErrorBoundary可以帮助我们避免这种错误,也能正常渲染。错误边界是一个可以捕获子组件树任何位置产生的javascript错误,错误边界会记录这些错误,并显示回退UI而非崩溃的组件树。

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

const Broken = (props) => {
  throw new Error("Oh No");
  return <>Never Getting Here</>
}

function App() {
  return (
    <>
      <div>Before</div>
      <ErrorBoundary fallback={err => err}>
        <Broken />
      </ErrorBoundary>
      <div>After</div>
    </>
  );
}

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

在该段代码中将Broken组件中使用throw抛出一个错误,正常情况下页面是不能渲染出数据的,但是现在我们用ErrorBoundary包裹组件可能会产生错误的组件,页面照常能够正常渲染。