【问题标题】:How to render a component using innerHTML in React jsx如何在 React jsx 中使用 innerHTML 渲染组件
【发布时间】:2019-05-17 14:16:18
【问题描述】:
我目前正在编写将在两个视图(图形和列表)之间切换的功能。二是视图容器的类名。
toggleGraphView() {
const two = document.getElementsByClassName('two')[0];
two.innerHTML = '<span>Graph View!</span>'
}
toggleListView() {
const two = document.getElementsByClassName('two')[0];
two.innerHTML = "<ShotLog shotLog={this.state.shotLog}/>"
}
组件切换到图形视图文本就好了(“图形视图!”),但是当我尝试切换回列表视图时,我什么也得不到。触发 toggleListView 后,在 chrome 工具中,这两个容器包含 <shotlog shotlog="{this.state.shotLog}/"></shotlog>。我需要它看起来像 <ShotLog shotLog={this.state.shotLog}/> 才能正确传递道具。
我不确定额外的报价是从哪里来的。有什么想法吗?
【问题讨论】:
标签:
javascript
html
css
reactjs
jsx
【解决方案1】:
您不能通过将 React 组件放入字符串来创建它们,使用 JSX,您的代码可以缩短为以下内容:
this.state.showGraph ? <span>Graph View!</span> : <ShotLog shotLog={this.state.shotLog} />
使用三元条件,你可以根据变量的值来决定渲染什么,showGraph
showGraph 将存储在组件的状态中,可通过this.state 访问,当您想更改状态中某些内容的值时,您必须调用setState,这将导致您的组件重新渲染所有内容在您的屏幕上显示您想要的内容
工作示例:
class ShotLog extends React.Component {
render() {
return <div>Hi I'm a ShotLog</div>
}
}
class App extends React.Component {
constructor(props){
super(props)
this.state = { showGraph: true }
}
handleClick = ev => {
this.setState({ showGraph: !this.state.showGraph })
}
render() {
return (
<div>
{this.state.showGraph ?
<span>Graph View!</span>
:
<ShotLog />}
<button onClick={this.handleClick}>Switch me !</button>
</div>
)
}
}
ReactDOM.render(
<App/>,
document.getElementById('react')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
<div id="react"></div>
您将在以下官方文档中找到 JSX 的基础知识:https://reactjs.org/docs/introducing-jsx.html
您可以在此处了解有关组件状态的更多信息:https://reactjs.org/docs/state-and-lifecycle.html
【解决方案2】:
我不是 ReactJS 专家,但我认为您应该返回正确的内容,而不是尝试通过 JS 更改它:
toggleView() {
if (this.isGraphView()) {
return <span>Graph View!</span>;
} else {
return <ShotLog shotLog={this.state.shotLog}/>
}
}
【解决方案3】:
结合@Justinas 的回答,您可以尝试进行条件渲染,而不是使用纯 JS。你可以试试这样:
MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {currView: 'graph'};
}
handleToggle() {
if (this.state.currView === 'graph') {
this.setState({currView: 'otherView'});
} else {
this.setState({currView: 'graph'});
}
}
render() {
if(this.state.currView === 'graph') {
// render your 'graph' view
} else {
// render some other view
}
}
}
对组件状态的更改将导致重新渲染,因此它应该完全改变以前存在的任何内容。只要确保你有一些可以切换或更新状态的东西:)
附:对不起,如果我在反应相关的语法中犯了一些错误。现在没有 IDE 哈哈
【解决方案4】:
您可以使用 react 方式来切换视图,而不是尝试直接使用 document.getElementsByClassName 访问 dom。你可以参考我下面的例子。
class TestComponent
{
constructor(props) {
super(props);
this.state = {
view: 'list',
shotLog: someVal
}
handleToggle() {
const modifiedView= this.state.view == 'graph'? 'list': 'graph';
this.setState(() => {
return {view: modifiedView};
});
}
}
render() {
const {view, shotLog} = this.state;
<div>
<button onClick={this.handleToggle}> Toggle </button>
{view == 'graph'} && <span> Graph View! </span>
{view == 'list'} && <ShotLog shotLog={shotLog} />
</div>
}
}