使用 Ramda 和 React 来设置状态
Using Ramda with React to setState
我正在尝试使用 ramda
进行过滤。我已经详细阅读了 Ramda 文档。
但是,我尝试过滤它对我的 setState
和控制台日志没有影响。
实时代码示例:
https://codesandbox.io/s/qY219X102
我的尝试:
import React from 'react';
import { render } from 'react-dom';
import R from 'ramda';
const o = {
movies: [
{ name: 'movie 1', genres: ['comedy', 'action'] },
{ name: 'movie 2', genres: ['action', 'drama'] },
{ name: 'movie 3', genres: ['drama', 'action'] },
],
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
movies: o,
};
}
getGenre = () => {
R.pipe(
R.prop(o.movies),
R.filter(
R.and(
R.propSatisfies(R.find(R.equals('action')), 'genres'),
R.propSatisfies(R.find(R.equals('comedy')), 'genres'),
),
),
);
this.setState({ o });
console.log('genre', o);
};
render() {
const rawmovies = Object.keys(o).map(e => o[e]);
const movies = [].concat.apply([], rawmovies);
return (
<div>
<button onClick={this.getGenre}>Action genre</button>
{movies.map(e => <span key={e.name}> {e.name}</span>)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
我检查了你的代码并做了一些修改以允许过滤:
import React from 'react';
import { render } from 'react-dom';
import R from 'ramda';
const o = {
movies: [
{ name: 'movie 1', genres: ['comedy', 'action'] },
{ name: 'movie 2', genres: ['action', 'drama'] },
{ name: 'movie 3', genres: ['drama', 'action'] },
],
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
movies: o.movies,
};
}
getGenre = () => {
const filter = R.pipe(
R.prop('movies'),
R.filter(
R.and(
R.propSatisfies(R.find(R.equals('action')), 'genres'),
R.propSatisfies(R.find(R.equals('comedy')), 'genres'),
),
),
);
const result = filter(o);
this.setState({ movies: result });
};
render() {
return (
<div>
<button onClick={this.getGenre}>Action genre</button>
{this.state.movies.map(e => <span key={e.name}> {e.name}</span>)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
抱歉,如果我没答对你的问题。
问题是 Ramda returns 一个函数,而您没有存储和使用该函数进行过滤。
同样在渲染方法中你没有使用状态下的电影。
至于实际过滤本身,我发现这个 Ramda 片段更容易阅读:
filter(both(
where({genres: contains('drama')}),
where({genres: contains('action')})
))
您可以在 Ramda REPL. And you can always see the docs for filter
, both
, where
, and contains
on the Ramda site.
上看到实际效果
我正在尝试使用 ramda
进行过滤。我已经详细阅读了 Ramda 文档。
但是,我尝试过滤它对我的 setState
和控制台日志没有影响。
实时代码示例:
https://codesandbox.io/s/qY219X102
我的尝试:
import React from 'react';
import { render } from 'react-dom';
import R from 'ramda';
const o = {
movies: [
{ name: 'movie 1', genres: ['comedy', 'action'] },
{ name: 'movie 2', genres: ['action', 'drama'] },
{ name: 'movie 3', genres: ['drama', 'action'] },
],
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
movies: o,
};
}
getGenre = () => {
R.pipe(
R.prop(o.movies),
R.filter(
R.and(
R.propSatisfies(R.find(R.equals('action')), 'genres'),
R.propSatisfies(R.find(R.equals('comedy')), 'genres'),
),
),
);
this.setState({ o });
console.log('genre', o);
};
render() {
const rawmovies = Object.keys(o).map(e => o[e]);
const movies = [].concat.apply([], rawmovies);
return (
<div>
<button onClick={this.getGenre}>Action genre</button>
{movies.map(e => <span key={e.name}> {e.name}</span>)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
我检查了你的代码并做了一些修改以允许过滤:
import React from 'react';
import { render } from 'react-dom';
import R from 'ramda';
const o = {
movies: [
{ name: 'movie 1', genres: ['comedy', 'action'] },
{ name: 'movie 2', genres: ['action', 'drama'] },
{ name: 'movie 3', genres: ['drama', 'action'] },
],
};
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
movies: o.movies,
};
}
getGenre = () => {
const filter = R.pipe(
R.prop('movies'),
R.filter(
R.and(
R.propSatisfies(R.find(R.equals('action')), 'genres'),
R.propSatisfies(R.find(R.equals('comedy')), 'genres'),
),
),
);
const result = filter(o);
this.setState({ movies: result });
};
render() {
return (
<div>
<button onClick={this.getGenre}>Action genre</button>
{this.state.movies.map(e => <span key={e.name}> {e.name}</span>)}
</div>
);
}
}
render(<App />, document.getElementById('root'));
抱歉,如果我没答对你的问题。
问题是 Ramda returns 一个函数,而您没有存储和使用该函数进行过滤。
同样在渲染方法中你没有使用状态下的电影。
至于实际过滤本身,我发现这个 Ramda 片段更容易阅读:
filter(both(
where({genres: contains('drama')}),
where({genres: contains('action')})
))
您可以在 Ramda REPL. And you can always see the docs for filter
, both
, where
, and contains
on the Ramda site.