我有一个如下所述的容器和演示组件
Components
|-Containers
|- App.tsx
|- ServiceContainer.tsx
|-Presentation
|-ServiceList.tsx
|-ServiceListItem.tsx
问题:我已经阅读过演示容器不应具有任何状态,而只能从props渲染数据,而且传递的props不能映射到本地状态-很好,但是我需要在 ServiceListItem上悬停状态。悬停时,我需要显示服务的描述。如何在不在演示文稿组件上创建本地状态的情况下执行此操作?我是否需要为演示组件创建动作和缩减器?
这是我的密码。我有安装商店,减速器和操作器。
App.tsx
import * as React from "react";
import ServicesContainer from "./containers/ServicesContainer";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { IStateProps, IDispatchProps, ServiceListProps } from "../types/services/serviceModel";
import ServiceActionCreators from "../actions/serviceRecordActions";
class App extends React.Component<ServiceListProps>{
constructor(props){
super(props)
}
render(){
return(
<ServicesContainer {...this.props}/>
)
}
}
function mapStateToProps(state:any): IStateProps{
return {services: state.serviceRecords}
}
function mapDispatchToProps(dispatch:any): IDispatchProps{
const dispatchProps : any = {
fetchServiceRecords : ServiceActionCreators.fetchServiceRecords,
addServiceRecord: ServiceActionCreators.addServiceRecord,
removeServiceRecord: ServiceActionCreators.removeServiceRecord
}
return bindActionCreators(dispatchProps, dispatch);
}
ServiceContainer.tsx
import * as React from "react";
import ServiceList from "../presentations/ServiceList";
import { ServiceListProps } from "../../types/services/serviceModel";
const ServicesContainer = (props: ServiceListProps) => {
return (
<ServiceList {...this.props}/>
);
}
export default ServicesContainer;
ServiceList.tsx
import * as React from "react";
import { ServiceListProps} from "../../types/services/serviceModel";
import ServiceListItem from "../presentations/ServiceListItem";
// Stateless Component
class ServiceList extends React.Component<ServiceListProps> {
constructor(props){
super(props);
}
render(){
return (
<ul>
{
this.props.services.map((s) => (
<ServiceListItem
key={s.service.Id}
service={s.service}
/>
))
}
</ul>
)
}
}
export default ServiceList;
ServiceListItem.tsx
import * as React from "react";
import {ServiceListItemModel} from "../../types/services/serviceModel";
// Stateless Component
const ServiceListItem = (props:ServiceListItemModel) => {
return(
<li>
{props.service.Name}
<a href="#" >Remove</a>
// On Hover, I want to show this <p> tag
<p > - {props.service.Description}</p>
</li>
)
}
export default ServiceListItem;
更新(带有解决方案) 这按预期工作。没有道具可以显示状态图,仅显示道具数据
class ServiceListItem extends React.Component<ServiceListItemProps, any> {
constructor(props){
super(props);
// only UI state changes
this.state = {showDescription: false}
}
toggleDescription(){
this.setState(prevState => ({showDescription: !prevState.showDescription}))
}
render(){
return(
<li
onMouseOver={() => this.toggleDescription()}
onMouseLeave={() => this.toggleDescription()}
>
{this.props.service.Name}
<a href="#" >Remove</a>
{this.state.showDescription &&
<p > - {this.props.service.Description}</p>
}
</li>
)
}
}
答案 0 :(得分:1)
的确,表示组件不应具有状态,但是这里的状态纯粹是指从云或某些IO获取的数据驱动状态。这种状态需要在容器组件中处理。
由丹·阿布拉莫夫(Dan Abramov)在他的article中引用:
- 修饰性成分与事物的外观有关。
- 很少有自己的状态(当有状态时,它是UI状态而不是数据状态)。
在呈示形式的ServiceListItem组件中,具有本地状态将非常好,该状态将控制悬停行为,因为它是仍然不知道数据驱动状态的UI构造。
答案 1 :(得分:0)
您可以使用on hover事件并将状态设置回如下所示的容器状态
ServiceList.tsx
// Stateless Component
class ServiceList extends React.Component<ServiceListProps> {
constructor(props){
super(props);
this.state = {hover: false};
}
//note here
onHover(status: boolean) {
this.setState({hover: status});
}
render(){
return (
<ul>
{
this.props.services.map((s) => (
<ServiceListItem
key={s.service.Id}
service={s.service}
hover={this.state.hover}
onHandleHoverEvent={this.onHover}
/>
))
}
</ul>
)
}
}
export default ServiceList;
然后
// Stateless Component
const ServiceListItem = (props:ServiceListItemModel) => {
return(
<li onMouseOver={() => this.props.onHandleHoverEvent(true)} onMouseOut={() => this.props.onHandleHoverEvent(false)}>
{props.service.Name}
<a href="#" >Remove</a>
{ props.hover &&
<p> - {props.service.Description}</p>
}
</li>
)
}
export default ServiceListItem;