如何有条件地呈现状态属性
Posted
技术标签:
【中文标题】如何有条件地呈现状态属性【英文标题】:How to conditionally render an attribute of state 【发布时间】:2019-10-28 08:56:58 【问题描述】:我正在尝试获取一个下拉菜单来显示用户从上一页中选择的主题的名称(目前,它默认为“主题”)。
虽然我能够在控制台中获取 $r.state.topics[$r.state.topicSelected].name
,但在我的代码中输入 this.state.topics[this.state.topicSelected].name
时出现未定义的错误。
所以,我尝试使用条件渲染将“主题”作为默认渲染,而主题本身是通过获取请求收集的。
<select
value=this.state.topicSelected
onChange=this.onTopicClick
className="sort"
data-element>
// Add this option in the .then() when populating siteCategories()
[<option key=this.state.topicSelected
value=this.state.topicSelected>(if
(this.state.topics[this.state.topicSelected].name == undefined)
'Topics'
else
this.state.topics[this.state.topicSelected].name
)
</option>].concat(
this.state.topics.map(function (topic)
return (<option
key=topic.id
value=topic.id>topic.name</option>);
))
</select>
我遇到了一个意外的令牌错误,但我尝试了各种语法组合但没有成功 - 如何正确运行这种条件格式?
【问题讨论】:
这是什么,$r
?你是说this
是的,$r 是您在 chrome 上的 react 开发工具中获得 this
的方式
【参考方案1】:
您可以使用三元表达式? :
。像这样,
this.state.topics[this.state.topicSelected] ? this.state.topics[this.state.topicSelected].name : 'Topics'
由于undefined
是一个假值,当this.state.topics[this.state.topicSelected]
未定义时,它将返回“主题”。
<select
value=this.state.topicSelected
onChange=this.onTopicClick
className="sort"
data-element>
<option key=this.state.topicSelected
value=this.state.topicSelected>
this.state.topics[this.state.topicSelected] ?
this.state.topics[this.state.topicSelected].name : 'Topics'
</option>
this.state.topics.map(function (topic)
return (<option key=topic.id value=topic.id>topic.name</option>);
)
</select>
就你做事的方式而言,还有一些其他问题,但我认为它们与你的问题无关。一方面,您正在将列表的第一个选项更改为您选择的值。相反,您应该设置 select 的值,该值会自动从列表中选择正确的选项。我会这样写:
render()
<select
value=this.state.topicSelected
onChange=this.onTopicClick
className="sort"
data-element>
<option value=0>Topics</option>
this.state.topics.map(topic =>
<option key=topic.id value=topic.id>topic.name</option>))
</select>
【讨论】:
谢谢,但不幸的是我仍然收到Cannot read property 'name' of undefined
哦,现在我明白了。让我重写它。
我想我可能还需要对 key
和 value
应用相同的逻辑 - 当我选择一个主题时,它会覆盖“主题”,因此标题的名称会出现两次跨度>
就您做事的方式而言,还有一些其他问题,但我认为它们与您的问题无关。一方面,您正在将列表的第一个选项更改为您选择的值。相反,您应该设置 select 的值,该值会自动从列表中选择正确的选项。
好的,谢谢。这就是我最终想要实现的目标,另一个问题可能是 initialState
设置为 0
所以当用户返回一个页面时,它总是默认为 Topics
【参考方案2】:
您也可以将其设为受控组件,并默认状态如下
function App()
const [topics] = useState(["Math", "Geography"]);
const [selectedTopic, setSelected] = useState("Topic");
return (
<select
value=selectedTopic
onChange=(e) => setSelected(e.target.value)
className="sort"
>
<option>
Topic
</option>
topics.map(topic => (
<option key=topic value=topic>
topic
</option>
))
</select>
);
组件的类版本
class App extends React.Component
state =
topics: ["Math", "Geography"],
selectedTopic: "Topic",
render()
const selectedTopic, topics = this.state;
return (
<select
value=selectedTopic
onChange=(e) => this.setState( selectedTopic: e.target.value )
className="sort"
>
<option>
Topic
</option>
topics.map(topic => (
<option key=topic value=topic>
topic
</option>
))
</select>
);
此外,在您的渲染方法中,您不能有 if 语句,因为其中只允许使用 javascript 表达式。如果您需要使用条件语句,请使用三元运算符或使用 if 块创建一个函数,该函数可以从 render 中调用。你可以阅读更多关于表达式here
【讨论】:
如果写成类组件会更好。 (因为他使用的是一个,所以钩子是完全不同的学习曲线)以上是关于如何有条件地呈现状态属性的主要内容,如果未能解决你的问题,请参考以下文章
是否可以有条件地仅在 React 的输入标签中呈现占位符属性?
我应该使用带有 render 属性的 ui:fragment 来有条件地在带有 JSF 2.2 的 Facelets 中呈现 HTML 标记吗?