Как показано в официальных документах redux -> https://redux.js.org/basics/usage-with-react, логика и предварительные настройки должны быть связаны вместе.
Вопрос в том, реально ли, что мы не можем разделить их, чтобы сделать наш код более понятным?
Например, какой-то компонент из официальных документов redux.js.org. Итак, логика и пресеты в нем вместе, и это выглядит не так хорошо и ясно:
import React from 'react'
import { connect } from 'react-redux'
import { addTodo } from '../actions'
let AddTodo = ({ dispatch }) => {
let input
return (
<div>
<form
onSubmit = {e => {
e.preventDefault()
if (!input.value.trim()) {
return
}
dispatch(addTodo(input.value))
input.value = ''
}}
>
<input
ref = {node => {
input = node
}}
/>
<button type = "submit">
Add Todo
</button>
</form>
</div>
)
}
AddTodo = connect()(AddTodo)
export default AddTodo
P.S. Еще видел такой вопрос: Разделение презентационной и логической составляющих react / redux, это не то же самое.
UPD: I had separate the logic into onSubmit module and component presentation. But > for now I get an error -
TypeError: Cannot call a class as a function:
/ * ПРЕЗЕНТАЦИЯ * /
import React from 'react';
import { connect } from 'react-redux';
import AddTodo from '../../Actions/AddTodo'
import addTodo from '../../Modules/handleClick'
class AddTodos extends React.Component{
componentDidMount() {
console.info(addTodo()); // for test. Get "TypeError: Cannot call a class as a function"
}
render() {
return (
<form>
<input type = "text" placeholder = "Your text" />
<button type = "submit">Add todos</button>
</form>
);
}
}
export default AddTodos;
/ * ОТПРАВИТЬ МОДУЛЬ * /
import { connect } from 'react-redux';
import AddTodo from '../Actions/AddTodo'
let addTodo = ({ dispatch }) => {
if (document.readyState === 'complete') {
let form = document.querySelector('form');
form.addEventListener('submit', handleClick);
function handleClick(e) {
e.preventDefault();
let input = document.querySelector('input');
dispatch(AddTodo(input.value));
input.value = '';
}
}
}
addTodo = connect()(addTodo);
export default addTodo;
Я разделил этот случай на модуль onSubmit и просто на презентацию. Но теперь я получаю ошибку TypeError: Cannot call a class as a function при вызове модуля onSubmit внутри component. UPD вопрос
Вы используете создателя действий как функцию. addTodo - это не функция, это средство создания действия и должно использоваться с диспетчеризацией.





Из той же документации, которую вы дали:
Sometimes it's hard to tell if some component should be a presentational component or a container. For example, sometimes form and function are really coupled together, such as in the case of this tiny component:
AddTodo is an input field with an “Add” buttonTechnically we could split it into two components but it might be too early at this stage. It's fine to mix presentation and logic in a component that is very small. As it grows, it will be more obvious how to split it, so we'll leave it mixed.
Итак, да, вы правы, лучше разделить наши презентационные и контейнерные компоненты, и это очень хорошо объяснено в документации, как вы заявили. Приведенный вами пример - просто исключение.
Вот как можно разделить компоненты:
AddTodo
import React from "react";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { addTodo } from "../actions";
import AddTodoForm from "./AddTodoForm";
const AddTodo = ( props ) => {
const handleAddTodo = todo => props.dispatch( addTodo( todo ) );
return (
<AddTodoForm addTodo = {handleAddTodo} />
);
};
export default connect()( AddTodo );
AddTodoForm
import React from "react";
const AddTodoForm = ( props ) => {
let input;
const handleClick = () => {
props.addTodo( input.value );
input.value = "";
};
return (
<div>
<input
ref = {( node ) => {
input = node;
}}
/>
<button
onClick = {handleClick}
>
Add Todo
</button>
</div>
);
};
export default AddTodoForm;
Я настоятельно рекомендую вам посмотреть видео Redux на Egghead от Дэна Абрамова (создателя Redux). Вы поймете логику Redux с нуля, посмотрев эти видео. Есть две части, смотрите обе части. Пока я изучал Redux, я смотрел их и писал все коды во время просмотра. После этого я создал репо: https://github.com/devserkan/react-with-idiomatic-redux
Вы можете клонировать это репо и играть как хотите.
Спасибо, но я не могу понять, как разделить презентацию и логику в данном случае. Может ты знаешь и сможешь это сделать? Я обновил вопрос и реализовал свою реализацию, но это не сработало ...
В этом случае будет имя компонента AddTodoForm, включающее простую форму. У него будет функция handleSubmit, и он будет передавать входное значение реальной функции, которая будет выполнять отправку. Эта функция будет в нашем компоненте-контейнере и передаст эту функцию в наш AddTodoForm. Итак, для простой формы все становится сумасшедшим. Вот почему в документации говорится, что для этого этапа еще слишком рано. Позвольте мне сделать это, если у меня будет время.
Рассмотрите возможность использования шаблона контроллер / презентационный компонент medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7 d0
Спасибо, что указали на это @ AnthonyManning-Franklin. Я пересмотрел свой код и написал компоненты как функции.
Вы можете переместить обработчик
onSubmitв отдельный метод класса,