选择实用程序

pick 实用程序允许您读取深层属性值,同时保持状态的反应性,从而简化了对象状态的处理。

为什么使用 pick 实用程序?

让我们看一个简单的用户对象状态。

javascript
const [currentUser] = state(null)

用户数据模型看起来像这样:

typescript
interface User {
    name: string
    emails: string[]
    skils: {
        name: string
        yearsOfExperience: number
    }[]
    type: 'Admin' | 'User' | 'Partner'
    jobs: {
        name: string
        startingDate: Date
        endDate?: Date
        company: {
            name: string
            website: string
            logo: string
        }
    }[]
}

现在我们可以尝试显示状态中设置的这个用户信息。

javascript
html`
    <h3>${currentUser().name}</h3>
    <p>email: ${currentUser().email}</h3>
    <h4>Skills:</h4>
    <ul>${repeat(currentUser().skills, renderSkil)}</ul>
    <h4>Jobs:</h4>
    <ul>${repeat(currentUser().jobs, renderJob)}</ul>
`.render(document.body)

这完美地显示了一切。但是,如果这是一个发生变化的对象,则不会重新渲染任何内容,因为所有内容都是静态渲染的。简单的解决方案是使用函数动态渲染所有内容。

javascript
html`
    <h3>${() => currentUser().name}</h3>
    <p>email: ${() => currentUser().email}</h3>
    <h4>Skills:</h4>
    <ul>${repeat(() => currentUser().skills, renderSkil)}</ul>
    <h4>Jobs:</h4>
    <ul>${repeat(() => currentUser().jobs, renderJob)}</ul>
`.render(document.body)

或者,您可以使用 pick 选择要从状态渲染的属性。

javascript
html`
    <h3>${pick(currentUser, 'name')}</h3>
    <p>email: ${pick(currentUser, 'email')}</h3>
    <h4>Skills:</h4>
    <ul>${repeat(pick(currentUser, 'skills'), renderSkil)}</ul>
    <h4>Jobs:</h4>
    <ul>${repeat(pick(currentUser, 'jobs'), renderJob)}</ul>
`.render(document.body)

pick 实用程序只是一个函数,也可以在模板之外使用。

javascript
console.log(pick(currentUser, 'jobs')())

深刻的价值观

使用 pick 的最佳部分是它能够让您选择深度值。例如,让我们访问我们当前用户的第三份工作公司网站。

javascript
html`${pick(currentUser, 'jobs.2.company.website')}`

正如您所看到的,您可以使用点符号来深入访问属性,并且当这些值发生变化时,所有内容都会重新渲染。

未定义的值

pick 实用程序还通过防止在尝试读取不存在的属性时抛出错误来提供针对未定义值的保护。

pick 帮助程序将捕获错误并简单地返回可由代码呈现或读取的 undefined

javascript
html`${pick(currentUser, 'jobs.2.company.url')}`.render(document.body)
// renders "undefined"

映射器功能

pick 实用程序接受可选的第三个参数 - 一个映射器函数,用于在返回所选值之前对其进行转换。

javascript
html`
    <h3>${pick(currentUser, 'name', (name) => name.toUpperCase())}</h3>
    <p>
        Member since:
        ${pick(currentUser, 'jobs.0.startingDate', (date) =>
            date.toLocaleDateString()
        )}
    </p>
`.render(document.body)

这对于在呈现或使用选取的值之前格式化值、转换类型或对其应用任何转换非常有用。

编辑本文档