我正在尝试编写可重用的组件,以便在将来的项目中使用。只要组件“T”没有嵌套在html元素中,我编写的代码就可以工作。
我写的localize.js如下;
import React, { Component } from 'react';
const Localizeit = (props) => {
let textWithLanguageProps = React.Children.map(props.children, function(child) {
let { s } = child.props;
if (React.isValidElement(child)){
return React.cloneElement(child, {lang : props.data[s]} );
}
return child;
});
return (
<div>
{textWithLanguageProps}
</div>
)
}
const T = ({lang}) => (
<span>{lang}</span>
)
export { Localizeit , T};
在我使用我的翻译组件的组件中,我将所有要在其中呈现的内容包装起来,然后组件检查是否存在有效的react元素。如果有,那么他们用道具和字符串一起渲染。只要组件没有嵌套,这就可以工作。我无法找到解决这个问题的方法。我是否必须深入检查html元素是否具有嵌套的反应组件?
demo.js如下;
import React, { Component } from 'react'
import { render } from 'react-dom'
import { Localizeit, T } from './localize';
const en = {
hello: "hello world",
works: "it works weirdly enough"
}
const es = {
hello: "hola mundo",
works: "funciona bastante raro"
}
const tr = {
hello: "merhaba dunya",
works: "garip bir sekilde calisiyor."
}
class Demo extends Component {
constructor(props) {
super(props);
this.state = {
lang: en
}
}
render() {
return (
<div>
<Localizeit data={this.state.lang}>
<button onClick={() => this.setState({ lang: en })}>en</button>
<button onClick={() => this.setState({ lang: tr })}>tr</button>
<button onClick={() => this.setState({ lang: es })}>es</button>
<h1>react-localizeit Demo</h1>
<T s="hello" />
<br />
<p>Following doesn't work</p>
<span><T s="works" /></span>
</Localizeit>
</div>
)
}
}
render(<Demo />, document.getElementById('root'))
可以找到工作演示here。
答案 0 :(得分:1)
我有渲染道具版的工作原型。在这里,我可以按照自己的意愿进行嵌套,但它仍然有效。
const en = {
hello: "hello world",
works: "it works weirdly enough"
};
const es = {
hello: "hola mundo",
works: "funciona bastante raro"
};
const tr = {
hello: "merhaba dunya",
works: "garip bir sekilde calisiyor."
};
const data = { en, es, tr };
class Localize extends React.Component {
constructor(props) {
super(props);
this.state = {
lang: props.initialLanguage || "en"
};
}
render() {
if(!this.props.data) return null;
return this.props.render({
selectedLanguage: this.state.lang,
onChange: lang => this.setState({ lang }),
dict: (this.props.data[this.state.lang]) || {}
});
}
}
const App = () => (
<Localize
data={data}
initialLanguage="en"
render={({ dict, onChange, selectedLanguage}) => (
<div>
<h1>localize</h1>
<div>You have selected: {selectedLanguage}</div>
<button onClick={() => onChange("en")}>en</button>
<button onClick={() => onChange("es")}>es</button>
<button onClick={() => onChange("tr")}>tr</button>
<div>{dict.hello}</div>
<div>{dict.works}</div>
<div>
<div>
<span>{dict.hello}</span>
</div>
<div>
<span>{dict.works}</span>
</div>
</div>
</div>
)}
/>
);
ReactDOM.render(<App />, document.querySelector("#root"));
答案 1 :(得分:0)
React组件类型是一个函数,而不是一个常规组件,它是一个字符串。
这是我的解决方案:
function buildChildrenWithProps(children, props) {
return React.Children.map(children, (child) => {
// if not a valid Component
if (typeof child.type !== 'function') {
return child;
}
return React.cloneElement(child, Object.assign({}, child.props, props));
});
}
用法是:
render(){
const _children = buildChildrenWithProps(this.props.children, {/*props*/});
return (
<div>{_children}</div>
);
}