Подключение компонента с набранным реквизитом - PullRequest
0 голосов
/ 07 октября 2019

У меня есть компонент - App.tsx, который имеет определение типа для своих реквизитов. Пропорции включают в себя массив задач и создателя действий, которые будут введены с помощью connect (реагировать-редукса). Однако я не могу подключить компонент «App», скажем, «index.tsx», не пройдя эти необходимые операции. Есть ли альтернатива указанию этих реквизитов как опциональных в интерфейсе? Если они не являются обязательными, то я должен делать нулевые проверки везде, где я к ним обращаюсь.

Я прочитал с использованием приставки с машинописью среди другой документации, но не нашел ответов.

index.tsx =>

ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>,
    document.getElementById('root')
);

В приведенном выше коде есть ошибки, потому что компонент приложения нижеожидает два параметра - 'todos' и 'fetchTodos'

App.tsx =>

interface AppProps {
    todos: Todo[];
    fetchTodos(): any;
}

class _App extends Component<AppProps> {

    onButtonClick = (): void => {
        this.props.fetchTodos();
    }
    renderList(): JSX.Element[] | undefined {
        return this.props.todos.map((todo: Todo) => {
            return (
                <div key={todo.id}>{todo.title}</div>
            );
        });
    }
    render(): JSX.Element {
        return (
            <>
                <button onClick={this.onButtonClick}>Fetch</button>
                {this.renderList()}
            </>
        );
    }
}

const mapStateToProps = ({ todos }: StoreState, ownProps: AppProps): { todos: Todo[]; } => {
    return {
        todos
    };
};

export const App = connect(mapStateToProps, { fetchTodos })(_App);

Я хотел бы посмотреть, есть ли способ не указывать два реквизита как необязательныев интерфейсе AppProps, потому что они будут обязательно введены через connect.

Ответы [ 3 ]

0 голосов
/ 09 октября 2019

Вот как я решил выше:

interface ReduxInjectedProps{
   fetchTodos:typeof fetchTodos;
   todos:Todo[];
}  

class _App extends Component {
    get injected(){
       return this.props as ReduxInjectedProps;
    }
    onButtonClick = (): void => {
        this.injected.fetchTodos();
    }
    renderList(): JSX.Element[] | undefined {
        return this.injected.todos.map((todo: Todo) => {
            return (
                <div key={todo.id}>{todo.title}</div>
            );
        });
    }
    render(): JSX.Element {
        return (
            <>
                <button onClick={this.onButtonClick}>Fetch</button>
                {this.renderList()}
            </>
        );
    }
}

const mapStateToProps = ({ todos }: StoreState, ownProps: AppProps): { todos: Todo[]; } => {
    return {
        todos
    };
};

export const App = connect(mapStateToProps, { fetchTodos })(_App);
0 голосов
/ 09 октября 2019

Вы должны понимать, как Connect жонглирует типами.

Соединение лучше всего объясняется, если смотреть справа налево:

Ваш компонент принимает 2 реквизита: todos, fetchTodos.

Затем он смотрит на mapDispatchToProps. Ваша реализация этого обеспечивает fetchTodos. Новый список реквизитов: todos

Наконец, он смотрит на mapStateToProps: он предоставляет todos, но для выполнения функции требуется объект, содержащий: todos, fetchTodos

Ваш последний компонент содержит эти реквизиты: todos, fetchTodos

Это не то, что вы хотите, вы не хотите ни одного реквизита.

Вам необходимо настроить mapStateToProps функция:

const mapStateToProps = ({ todos }: StoreState, ownProps: {}): { todos: Todo[]; } => { return { todos }; 

или просто:

const mapStateToProps = ({ todos }: StoreState): { todos: Todo[]; } => { return { todos }; 
0 голосов
/ 07 октября 2019

Как и любой другой интерфейс TypeScript (или параметры функции или члены класса), вы можете объявлять необязательные типы, используя флаг ?:

interface AppProps {
    todos?: Todo[];
    fetchTodos()?: any;
}

Вы можете прочитать больше о необязательных параметрах и членахв документах .

Позже отредактируйте: Итак, вы хотите, чтобы сопоставленные реквизиты были исключены?

Обычно я объявляю типы своих пропов следующим образом:Я создал два интерфейса поддержки (один для сопоставленных реквизитов и один для реквизитов, которые я ожидал передать):

interface IOwnProps {
    fetchTodos(): any;
}

interface IPropsFromState {
    todos: Todo[];
}

type IProps = IOwnProps & IPropsFromState;

const mapStateToProps = (state: IRootState): IPropsFromState ({
   todos: state.todos  
});

class _App extends Component<IProps> {
 ...
}

export const App = connect(mapStateToProps)(_App);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...