Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs React中Redux状态的建模_Reactjs_Redux_React Redux - Fatal编程技术网

Reactjs React中Redux状态的建模

Reactjs React中Redux状态的建模,reactjs,redux,react-redux,Reactjs,Redux,React Redux,我正在寻找一种在React应用程序中建模Redux状态的干净方法。这里有一个我非常不喜欢的方法: const filmFuncs = { getTitles: function () { return this.currentTitles.map(function(film) { return film.title; }); } }; const defaultState = { 'currentTitles':

我正在寻找一种在React应用程序中建模Redux状态的干净方法。这里有一个我非常不喜欢的方法:

const filmFuncs = {
    getTitles: function () {
        return this.currentTitles.map(function(film) {
            return film.title;
        });
    }
};

const defaultState = {
    'currentTitles': [],
    ...filmFuncs,
};

var reducer = (state=defaultState, action) => {
    switch (action.type) {
        case "GET_FILMS": {
            return {...state, currentTitles: action.payload};
            break;
        }
    }
    return state;
};

export default reducer;
现在我可以调用这个.props.films.getTitles();而不是在我的组件中加入逻辑

或者,我想我可以建立一个单独的模型类并传入状态,类似这样:

var filmModel = new FilmModel(this.props.films);
filmModel.getTitles();
不过,我也不太喜欢这种方法。有什么想法吗

现在我可以调用这个.props.films.getTitles()而不是在我的组件中放入逻辑。

为什么您要避免在组件中添加逻辑

这种逻辑最好放在容器/智能组件中。在您的用例中,这样的组件将连接到Redux状态,执行getTitles选择并将所选数据传递给哑组件以呈现它

如果您确实希望避免将逻辑放入组件中,那么可以将其放入独立的helper/selector文件中,然后在connect中使用选择器。您可以使用类似“重新选择”的库来创建灵活的选择器

我建议阅读丹·阿布拉莫夫关于智能组件和哑组件的文章。链接

代码示例:

选择器文件:

export const titlesSelector = (state) => state.currentTitles.map(film => film.title)
组件文件:

//Imports
import { titlesSelector } from "./Selectors"

//The smart component

@connect(state => ({
  titles: titlesSelector(state)
}))
export default class SmartComponent extends React.Component {

  constructor() {
    super()

    this.getTitles = this.getTitles.bind(this)
  }

  render (
    return (
      <DumbComponent
        titles={this.props.titles}
      />
    )
  )
}

// The dumb component

const DumbComponent = ({ titles }) => 
<ul>
  {titles.map(title => <li>{title}</li>}
</ul>   
//导入
从“/Selectors”导入{titleSelector}
//智能组件
@连接(状态=>({
标题:标题选择器(州)
}))
导出默认类SmartComponent扩展React.Component{
构造函数(){
超级()
this.getTitles=this.getTitles.bind(this)
}
渲染(
返回(
)
)
}
//哑巴
常量组件=({titles})=>
    {titles.map(title=>
  • {title}
  • }
现在我可以调用this.props.films.getTitles();而不是在组件中添加逻辑。

为什么您要避免在组件中添加逻辑

这种逻辑最好放在容器/智能组件中。在您的用例中,这种组件将连接到Redux状态,执行getTitles选择,并将所选数据传递给哑组件以呈现它

如果您确实希望避免将逻辑放入组件中,则可以将其放入独立的帮助程序/选择器文件中,然后在连接中使用选择器。您可以使用类似于“重新选择”的库来创建灵活的选择器

我建议阅读丹·阿布拉莫夫关于智能组件和哑组件的文章

代码示例:

选择器文件:

export const titlesSelector = (state) => state.currentTitles.map(film => film.title)
组件文件:

//Imports
import { titlesSelector } from "./Selectors"

//The smart component

@connect(state => ({
  titles: titlesSelector(state)
}))
export default class SmartComponent extends React.Component {

  constructor() {
    super()

    this.getTitles = this.getTitles.bind(this)
  }

  render (
    return (
      <DumbComponent
        titles={this.props.titles}
      />
    )
  )
}

// The dumb component

const DumbComponent = ({ titles }) => 
<ul>
  {titles.map(title => <li>{title}</li>}
</ul>   
//导入
从“/Selectors”导入{titleSelector}
//智能组件
@连接(状态=>({
标题:标题选择器(州)
}))
导出默认类SmartComponent扩展React.Component{
构造函数(){
超级()
this.getTitles=this.getTitles.bind(this)
}
渲染(
返回(
)
)
}
//哑巴
常量组件=({titles})=>
    {titles.map(title=>
  • {title}
  • }

“您到底为什么试图避免在组件中添加逻辑?”--我想在这里谈谈我对可测试性的看法:我总是尽量保持组件的纤细,因为我不可能通过单元测试(all/most)的输出而跳入维护地狱现在,如果你所有的应用程序逻辑都在商店/实用程序类中,那么通过确保商店的可用性来执行单元测试是非常可行的对给定的操作执行正确的状态更改。如果有您想要重用的逻辑,但不一定是组件本身,该怎么办?以返回标题数组为例,如我的问题中所述。也许我希望有两个组件显示标题列表。一个组件为每个标题创建一组可单击的链接e、 另一个是列出包装在样式div中的每个标题。理想情况下,我希望共享getTitles()每个组件之间的逻辑。然后从单独的文件导出函数,并在需要时包含它。正如我前面提到的。无论如何,我理解。我应该指出,reducer不是存储选择器的正确位置(而且,将其直接放在状态中是疯狂的)首先,我只是对示例进行了改进,使其更适合您的用例。从组件中提取了选择器。其余的逻辑保持不变。@jankoritak谢谢,我同意这可能是实现我所追求的“您到底为什么试图避免在组件中添加逻辑?”--我想在这里谈谈我对可测试性的看法:我总是尽量使我的组件保持苗条,因为我不可能通过单元测试(all/most)的输出而跳进维护地狱现在,如果你所有的应用程序逻辑都在商店/实用程序类中,那么通过确保商店的可用性来执行单元测试是非常可行的对给定的操作执行正确的状态更改。如果有您想要重用的逻辑,但不一定是组件本身,该怎么办?以返回标题数组为例,如我的问题中所述。也许我希望有两个组件显示标题列表。一个组件为每个标题创建一组可单击的链接e、 另一个是列出包装在样式div中的每个标题。理想情况下,我希望共享getTitles()每个组件之间的逻辑。然后从单独的文件导出函数,并在需要时包含它。正如我前面提到的。无论如何,我理解。我应该指出,reducer不是存储选择器的正确位置(而且,将其直接放在状态中是疯狂的)首先。我刚刚对示例进行了改进,使其更适合您的用例。从组件中提取了选择器。其余逻辑保持不变。@jankoritak谢谢,我同意这可能是最好的方法,因为我刚刚告诉您,减速机中的
中断
是不必要的。您已经在前一行,因此