文字列をフォーマットする関数のパラメータに装飾された仮想DOMを使いたい
13193 ワード
何がやりたいか
{
"format": "こんにちは、{user.name}さん",
"params": {
"user": {
"name": "mpyw"
}
}
}
{
"format": "こんにちは、{user.name}さん",
"params": {
"user": {
"name": "mpyw"
}
}
}
みたいなAPIレスポンスが返ってきたとして,これをフロント側でユーザ名の部分を自由に装飾して表示させたい。
- 頻繁に新しいメッセージテンプレートが追加されるのに,いちいちそのたびにフロントエンドアプリの更新をさせたくない。(react-nativeとか使ってるとつらそう)
- HTMLタグを文字列としてそのまま埋め込むのってなんか違う気がするし,
dangerouslySetInnerHTML
も気軽には使いたくない。
文字列展開のみなら既に Matt-Esch/string-template などがあるんですが,なかなかJSXによる装飾に対応したのが無かったんですよね。例えばこうしたい。
こんにちは、mpywさん
実装してみる
String.prototype.replace
を使いたくなりますが,仮想DOMに対応できないので,String.prototype.split
で処理するのがミソです。
template.js
import React from 'react'
const renderValue = (Node) => {
if (typeof Node === 'function') {
return <Node />
}
if (Node === undefined) {
return null
}
return Node
}
const resolveParam = (params, key) => {
if (typeof key !== 'string') {
return params[key]
}
let param = params
for (const segment of key.split('.')) {
if (!param) return
param = param[segment]
}
return param
}
const template = (format, params) => {
const chunks = format.split(/\{(\{[\S\s]*?})}|\{([\S\s]*?)}/g)
const nodes = []
for (const [offset, value] of Object.entries(chunks)) {
switch (offset % 3) {
case 0:
nodes.push(value)
break
case 1:
if (value === undefined) continue
nodes.push(value)
break
case 2:
if (value === undefined) continue
nodes.push(renderValue(resolveParam(params, value)))
break
}
}
return nodes
}
export default template
使用例1
const { format, params } = {
format: 'こんにちは、{user.name}さん',
params: {
user: {
name: 'mpyw'
}
}
}
const decoratedParams = {
...params,
user: {
...params.user,
name: <span style={{ color: 'blue' }}>{params.user.name}</span>,
},
}
return <div>{template(format, decoratedParams)}</div>
こんにちは、mpywさん
使用例2
(<div>
{template(
'Hello, {p1}! Yeah, {p2}! Yo, {p3.foo}! {{This is escaped.}}',
{
p1: () => <span style={{ color: 'red' }}>World</span>,
p2: <span style={{ color: 'blue' }}>World</span>,
p3: {
foo: () => <span style={{ color: 'green' }}>World</span>,
},
}
)}
</div>)
Hello, World! Yeah, World! Yo, World! {This is escaped.}
仮想DOM生成関数と仮想DOM両対応,ドットチェインのネストにも対応,って感じで一通り必要そうなやつは実装しました。だいたいこれで事足りるはず。
ライブラリにするほどでもないよね?
Author And Source
この問題について(文字列をフォーマットする関数のパラメータに装飾された仮想DOMを使いたい), 我々は、より多くの情報をここで見つけました https://qiita.com/mpyw/items/66311481dc779ceb10ce著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .