是否可以在Redux / React中分离组件的表示和逻辑?

时间:2018-03-31 13:16:16

标签: reactjs redux

正如redux的官方文档中所示 - > https://redux.js.org/basics/usage-with-react,逻辑和预设必须捆绑在一起。

问题是 - 它是否真实,我们无法将它们分开以使我们的代码更清晰?

例如来自官方redux.js.org docs的一些组件。所以,逻辑和压力在一起,它看起来并不那么好和清晰:

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。 我也看到了这个问题:Separating presentational and logic components react/redux,这是不一样的。

  

UPD:   我将逻辑分成onSubmit模块和组件表示。但是&gt;现在我收到错误 - 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.log(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;

/ * ONSUBMIT MODULE * /

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;

1 个答案:

答案 0 :(得分:4)

从您提供的相同文档中:

  

有时很难判断某个组件是否应该是a   表示组件或容器。例如,有时形式   和功能真的耦合在一起,例如在这种情况下   微小的组成部分:

AddTodo is an input field with an “Add” button
     

从技术上讲,我们可以将其拆分为两个组件,但也可能   在这个阶段的早期。将演示文稿和逻辑混合在一起是很好的   组件非常小。 随着它的发展,如何变得更加明显   分开它,所以我们将它混合在一起。

所以是的,你是对的,最好将我们的展示和容器组件分开,并且如你所述,它在文档中得到了很好的解释。你给出的例子只是一个例外。

在这里您可以如何分离组件:

<强> 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;

我强烈建议您观看来自Dan Abramov(Redux的创作者)的Egghead上的Redux视频。观看这些视频后,您将从头开始了解Redux的逻辑。有两个部分,看两个部分。在我学习Redux的过程中,我观看了这些并编写了所有代码。之后我创建了一个回购:https://github.com/devserkan/react-with-idiomatic-redux

您可以按照自己的意愿克隆此回购并播放。