Javascript 您好,我无法使用React中的自定义观察者类将逻辑与UI解耦
所以我阅读了关于高阶组件的文档,认为重构我糟糕的monolit组件是个好主意 我的计划:Javascript 您好,我无法使用React中的自定义观察者类将逻辑与UI解耦,javascript,reactjs,request,observer-pattern,Javascript,Reactjs,Request,Observer Pattern,所以我阅读了关于高阶组件的文档,认为重构我糟糕的monolit组件是个好主意 我的计划: 订阅可观测值 获取数据并将其存储在地图中 通知更改并以某种方式更新UI(我是react新手,我知道有很多方法可以使用redux、mobx等)。但是我的小项目的目的是学习,我希望尽可能地保持事物的本地性(用于UI libs的ecxept) 下面的任何代码都可能是错误的 这是我的观察者课程,自1994年以来一直保持不变 export default class Observable { //observer
export default class Observable { //observer
listeners = new Set();
constructor(value) {
this.value = value;
}
get() {
return this.value;
}
set(newValue) {
if (newValue !== this.value) {
this.notify();
}
}
subscribe(listener) {
this.listeners.add(listener);
}
unsubscribe(listener) {
this.listeners.delete(listener);
}
notify() {
for (const listener of this.listeners) {
listener();
}
}
}
这是管理我观察到的类的订阅的高阶组件
import React from "react";
export default function withSubscription(WrappedComponent, api) {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
data: api.observableMapData //observable object
};
this.handleChange.bind(this);
}
handleChange() {
this.setState({
data: api.observableMapData
});
console.log("changed data") //never actually saw it in the console
}
componentDidMount() {
//observable object->getterfield->subscribe
api.fetchData();
api.observableMapData.dataSourceMap.subscribe(this.handleChange);
}
componentWillUnmount() {
//observable object->getterfield->unsubscribe
api.observableMapData.dataSourceMap.unsubscribe(this.handleChange);
}
render() {
return <WrappedComponent data={this.state.data} {...this.props} />;
}
};
}
和包装器函数
const api = new Api();
const TicketFormWithSubscription = withSubscription(
UiFormController,
api
);
export default TicketFormWithSubscription;
我就这样拿地图
export default class ApiService {
observableMapData = new DataSourceMap();
//singleton
constructor() {
if (!ApiService._instance) {
ApiService._instance = this;
// this.fetchData();
}
return ApiService._instance;
}
async fetchData() {
let tmpMap = new Map();
for (let value of this.observableMapData.dataSources) {
let data = await this.getAllItems(value[1]);
console.log(data);
tmpMap.set(value[1], data)
}
//setter
this.observableMapData.setDataSourceMap = tmpMap;
console.log(JSON.stringify(this.observableMapData + " fetched"));
}
...
}
因此,主要的问题是组件的加载速度比数据的检索速度快。当我打开Autocomplete时,会出现一个错误,因为值未定义,并且在获取数据后不会更新
最后,这里是道具流程
构造函数(道具){
超级(道具);
此.state={
observableMap:this.props.data,
confimOpen:错,
....
}
...
render(){
常量newProps={
项目:this.props.data.dataSourceMap.get('projects'),
组织:this.props.data.dataSourceMap.get('organizations'),
}
返回(
);
}
和materialUI自动完成组件
<Autocomplete
options={props.organizations.items}
margin="dense"
getOptionLabel={(option) => `${option.name}`}
renderInput={(params) => (
...
<Autocomplete
options={props.projects.items}
margin="dense"
getOptionLabel={(option) => `${option.name}`}
renderInput={(params) => (
...
`${option.name}`}
renderInput={(参数)=>(
...
`${option.name}`}
renderInput={(参数)=>(
...
我觉得我的方法很老,但可行,提前感谢你的新鲜眼光,我明白了
只需使用挂钩或
acync componentDidMount()
constructor(props) {
super(props);
this.state = {
observableMap: this.props.data,
confimOpen: false,
....
}
...
render() {
const newProps = {
projects : this.props.data.dataSourceMap.get('projects'),
organizations: this.props.data.dataSourceMap.get('organizations'),
}
return (
<TicketFormUi
{...newProps}
/>
);
}
<Autocomplete
options={props.organizations.items}
margin="dense"
getOptionLabel={(option) => `${option.name}`}
renderInput={(params) => (
...
<Autocomplete
options={props.projects.items}
margin="dense"
getOptionLabel={(option) => `${option.name}`}
renderInput={(params) => (
...