Как передать аргументы функции внутри compose?

#javascript #reactjs #redux #react-redux

#javascript #reactjs #redux #реагировать-redux

Вопрос:

У меня есть функция, подобная так:

 export const fireView = (prop1, prop2) => WrappedComponent =>
    class extends Component {
    //stuff in here
} 
  

затем hoc, подобный этому:

 export const withFireView = (prop1, prop2) =>
    fireView(prop1, prop2)
  

но теперь я хочу поместить эту функцию внутри compose, поскольку мне нужно вызвать ее с mapStateToProps

итак, я сделал это:

 compose (
    connect(mapStateToProps),
    fireView
)
  

но это ломается, потому что You must pass a component to the function returned by connect

итак, затем я избавляюсь от аргументов в функции fireview, и я думаю, что это сработает, но тогда все аргументы теперь не определены внутри функции, поскольку я их не передал

Есть ли какой-нибудь способ сделать что-то подобное:

 compose (
    connect(mapStateToProps),
    fireView(arg1, arg2)
)
  

но, очевидно, они там не определены, если это имеет смысл.

Комментарии:

1. Подумайте о добавлении большего контекста и тегов, чтобы было очевидно, на что вы ссылаетесь. Что это за язык / фреймворк?

2. @Willeman Я добавил redux, react и javascript. что еще нужно?

3. @RedBaron вам следует глубже ознакомиться с документами. compose — это средство расширения хранилища redux.js.org/api/compose . connect добавляет отправку и состояние к вашим реквизитам. react-redux.js.org/api/connect

4. @di3 Я понимаю это, я просто хочу добавить аргументы к одной из функций, которые я оборачиваю в compose

5. нет, вы этого не понимаете. sry connect не имеет ничего общего с compose. способ, которым вы используете react-redux, неверен. способ, которым вы используете compose, тоже неверен.

Ответ №1:

Вот полный рабочий пример:

 var Component = React.Component;
var render = ReactDOM.render;
var Provider = ReactRedux.Provider;
var connect = ReactRedux.connect;
var createStore = Redux.createStore;
var compose = Redux.compose;
    
const reducer = () => {return {}};
const mapStateToProps = () => {
  return {}; 
};
    
const wrapped = (props) => {
  return <div>{props.prop1} {props.prop2}</div>;
}
const fireView = (prop1, prop2) => WrappedComponent => {
  return class extends Component {
    render() {
      return <WrappedComponent prop1={prop1} prop2={prop2} />; 
    }   
  }
} 
    
const withFireView = (prop1, prop2) => fireView(prop1, prop2);
    
const withFireViewAndConnect = (arg1, arg2) => compose(connect(mapStateToProps), withFireView(arg1, arg2));
    
const App = withFireViewAndConnect('some', 'arg')(wrapped);
    
render(<Provider store={createStore(reducer)}><App /></Provider>, document.getElementById('demo'));  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/6.13.0/polyfill.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/6.0.0/react-redux.js"></script>

<div id="demo"></div>  

Ответ №2:

У меня было аналогичное требование, и я оказался на этой странице. Я предполагал, что мы не смогли понять вариант использования. Я попытаюсь обобщить это, а также предоставить ответ на него.

Объяснение

Мы можем использовать HOC (компоненты более высокого порядка) в React, чтобы абстрагироваться от общей функциональности. В документах React мы можем видеть обозначение ‘with’ для использования этих HOC. Я также создал несколько в своем приложении.

 withSplashScreenRedirect, withHistoryObject
  

Все эти HOC, которые я создал, принимают компонент (WrappedComponent) и возвращают компонент. (Никаких дополнительных аргументов не требуется).

const EnhancedComponent = higherOrderComponent(обернутый компонент);

Обычно у меня было бы от 2 до 3 HOC для каждого компонента уровня экрана. Запись этих HOC как функций, возвращающих другие функции, выглядит некрасиво. Redux предоставляет полезную функцию compose. Compose помогает нам связать эти HOC в более удобочитаемом виде.

Из документов compose.

Все, что делает compose, позволяет вам писать глубоко вложенные преобразования функций без смещения кода вправо. Не придавайте этому слишком большого значения!

Вскоре я захотел создать еще один HOC, который стандартизировал бы мою логику вызова API и логику обработки вызовов API. В этом случае мне пришлось отправить две дополнительные функции в мой HOC (вместе с обернутым компонентом).

 withApiCallHandler(WrappedComponent, makeApiCall, handleApiResponse)
  

Передача реквизитов в HOC не имеет большого значения. Вдокументах React есть хороший пример, объясняющий, как это сделать. Однако добавить такой HOC в цепочку compose не так просто. Я думаю, это то, что OP пытался спросить здесь.

Ответить

Я не смог найти способ связать такой HOC с compose. Возможно, это невозможно. Лучшим решением было бы инициализировать компонент withApiCallHandler отдельно, а затем связать его с compose.

Вместо

 const ComposedScreenComponent = compose(
  withHOC1,
  withHOC2,
  withHOC3(arg1, arg2)
)(ScreenComponent);
  

Сделайте это

 const withHOC3AndArgs = (WrappedComponent) =>
  withHOC3(WrappedComponent, arg1, arg2);

const ComposedScreenComponent = compose(
  withHOC1,
  withHOC2,
  withHOC3AndArgs(arg1, arg2)
)(ScreenComponent);
  

Это не лучший ответ на вопрос, но если кто-то застрял, то это решение, несомненно, будет хорошим обходным путем.

Ответ №3:

Вместо этого вы можете заставить withFireView возвращать функцию. Все будет работать.

 export const withFireView = (prop1, prop2) => () => fireView(prop1, prop2)