Справка по машинописи - переопределение реакции-редукса connect () с HOC - PullRequest
0 голосов
/ 20 сентября 2019

Надеюсь, что некоторые гуру Typescript могут помочь мне, потому что я новичок в этом.

Я пытаюсь использовать response-redux для сохранения состояния компонента в Redux, и у меня есть одна проблема - мне нужен способорганизовать многократно используемые компоненты таким образом, чтобы их состояние в глобальном хранилище не мешало друг другу.

Я был вдохновлен https://github.com/eloytoro/react-redux-uuid, который предлагает автоматически регистрировать состояние компонента в глобальном хранилище с использованием случайно сгенерированного UUIDпри монтировании, сохраняя состояние в этом «срезе» и удаляя его из резервной копии при размонтировании.При подключении он представляет «срез» данных состояния компонента для компонента в mapStatetoProps.Однако эта библиотека не функционирует и не соответствует Typescript.

Я адаптировал код так, чтобы его было легко:

  • AdminUserListContainer.tsx [повторно используемый компонент, состояние которого хранится в redux]
import { connectUUID,IRedux_UUID_DispatchProps } from 'lib/Redux_UUID';

export type TAdminUserListReduxState = {
  loadStatus:string,
  user_list:{user_list:any[]},
  loadErrorDesc:string
}
export interface AdminUserListProps {
  company_id:number,
  userClickPath:string
}
export const AdminUserListContainer:FunctionComponent<AdminUserListProps & TAdminUserListReduxState & IRedux_UUID_DispatchProps> = (props) => {
...
     props.dispatchUUID({
        type: 'SOME_ACTION',
        payload: {
          action_param1: param1;
        }
      });
...
};

const mapStateToProps = (state:{localState:TAdminUserListReduxState,globalState:any}) => {
  return state.localState;
};

export default connectUUID('AdminUserListContainer',mapStateToProps)(AdminUserListContainer);

Я в основном переопределяю connect () вact-redux своим собственным connectUUID (), который будет реализовывать HOC, который выполняет UUID, регистрирует / отменяет регистрацию + срезает специфичное для компонента состояние для передачив подпорки в mapStateToProps (эта идея была взята из библиотекиact-redux-uuid).Чтобы упростить, я не использую создателей действий, поэтому не отображаю диспетчеризацию, вместо этого я использую dispatchUUID ({action}) для прямой отправки действий (эта диспетчеризация будет вводить UUID в действие, чтобы редуктор знал, какой «срез» уменьшить на).

Полный код находится в: https://github.com/andrwo/react-redux-connectUUID/blob/master/Redux_UUID.tsx

Все это прекрасно работает. Когда мое приложение React запускается, оно регистрирует состояние локального компонента в uuid-избыточном коде.раздел (и удаляет его, когда этот компонент отключается):

enter image description here

Моя проблема в том, что в моей реализации connectUUID () HOC я использую any в нескольких объявлениях, так что это убрало мою проверку типов компонентов, которая все еще доступна, если вы использовали HOC () для connect () в Reaction-redux:

  • lib / Redux_UUID.tsx [библиотека connect_UUID]
export const connectUUID = (name:string, mapStateToProps?:any) => <T extends Matching<{}, T>>(Component:React.ComponentType<T>) => {
  const ConnectedComponent = connect(
    (mapStateToProps?wrapMapStateToProps(mapStateToProps, name):null)
  )(Component);
  class ConnectUUID extends React.Component<any> {
    uuid:string='';
    dispatchUUID = (action:any) => {
      const action2={
        ...action,
        meta: Object.assign(
            {},
            action.meta,
            name && {[NAME_KEY]: name},
            this.uuid && {[UUID_KEY]: this.uuid},
        )
      }
      this.props.dispatch(action2);
    }
    componentWillMount() {
      this.uuid = this.props.uuid || createUUID();

      if (!this.props.uuid) {
        this.props.dispatch({
          type: REGISTER,
          meta: {
            [UUID_KEY]: this.uuid,
            [NAME_KEY]: name
          }
        });
      }
    }
    componentWillUnmount() {
      if (!this.props.uuid) {
        this.props.dispatch({
          type: UNREGISTER,
          meta: {
            [UUID_KEY]: this.uuid,
            [NAME_KEY]: name
          }
      });
    }}
    render() {
      return (
        <ConnectedComponent
          {...this.props}
          dispatchUUID={this.dispatchUUID}
          uuid={this.uuid}
        />
      );
    }
  }
  return connect()(ConnectUUID);
};

Так что теперь, когда я использую этот компонент, он работает, потому что я использовал React.Component (любой), чтобы избавиться от ошибок типа, я также использую (любой) в mapStateToProps ... но ... я теряюПроверка типа реквизита компонента в коде VS (приведенный ниже код вызывает ошибку TS, поскольку invalidProp недопустим, разрешены только реквизиты (userClickPaths, company_id, uuid?)):

  • test.tsx [компонент, который использует AdminUserListContainer]
import AdminUserListContainer from 'component/svc/AdminUserListContainer';
...
(props) => return (
...
   <AdminUserListContainer
              userClickPaths={`${parentPath}/AdminUser`} 
              company_id={company_id}
              invalidProp={'blahBlah'}  // this prop should be invalid
              />

Я попытался просмотреть типизацию response-redux, чтобы увидеть, как они это делают, но меня все запутали все InferableProps и т.д ... все это выглядит очень плотно!

Может ли какой-нибудь гуру указать мне правильное направление, как я должен выполнять наборы функции connectUUID (), чтобы наборы выполнялись правильно?Заранее спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...