我正面临着redux和react-router-dom的问题

时间:2018-02-09 06:33:49

标签: reactjs redux react-router-v4 react-router-redux

我有以下代码。    main.js

class Main extends Component {
  constructor(props) {
    super(props);
    console.log('Main', props);
  }

  render() {
    return (  
      <BrowserRouter>
        <Switch >
          <Route exact path="/" component={LoginComponent}/>
          <Route  path="/signup" component={SignupComponent}/>
        </Switch>
      </BrowserRouter>
    );
  }
}

const mapState = ((state, ownProps) => {
  console.log('state', state);
  console.log('ownProps', ownProps);
  return{
    state,
    ownProps
  }
});

const actionProps = {
  login,
  signup
}
let mainApp = connect(mapState, actionProps)(Main);
export default mainApp;

我有这个App.js

let store = createStore(AppReducer);

class App extends Component {
  render() {
    return (
      <Provider store={store}>
         <Main />
      </Provider>
    );
  }
}

export default App;

我的问题是为什么我无法通过道具访问LoginComponent或SignupComponent中的操作/减少。

这是我在浏览器控制台上看到的输出。

state {loginReducer: {…}}
main.component.js:29 ownProps {}
main.component.js:12 Main {state: {…}, ownProps: {…}, login: ƒ, signup: ƒ}
auth.component.js:6 Login {match: {…}, location: {…}, history: {…}, staticContext: undefined}

任何人都可以帮帮我吗?如何解决这个问题?

更新: 我用这种方式修改了它:

<Route exact path="/" render={(routeProps) =>   
              <LoginComponent route={routeProps} store={this.props}/>
            }/>

但是,我不确定这是正确的做法吗?

2 个答案:

答案 0 :(得分:0)

您必须使用mapDispatchToProps来访问操作及其缩减器。像那样

import {bindActionCreators} from 'redux';
import {login, signup} from './actions'; // Your action file

...

const mapDispatchToProps = (dispatch) => {
 return bindActionCreators({
     login: login,
     signup: signup,
 }, dispatch)
}

export default connect(mapState, mapDispatchToProps)(Main);

答案 1 :(得分:0)

假设你在动作中导出了一些动作功能,那就简单了

import { store } from "reduxRoot/store";
import { login } from "./actions";

store.dispatch(login());

然后,您可以观察用mapStateToProps装饰的组件中的更新道具。

有些人可能会认为是hacky,因为根本没有将调度映射到道具。我发现这种方式更简单,我没有看到任何不利影响。如果有人可以提出为什么需要这样做,欢迎他们,我会学到一件事。

更新 - 实现更多细节;

const mapStateToProps = (state) => ({
   state: state, // only if you need the whole state in the component. 
   someRelevantPartOfState: state.login.relevant.part
})

使用上述内容connect LoginComponent Main。在您的代码中,只连接了let loginComponentWithState = connect(mapStateToProps)(LoginComponent); 个组件。试图与您的代码保持一致,

@connect(mapStateToProps)
class LoginComponent extends React.Component {
    ...
}

或者,我会使用装饰,因为它保留了组件名称。

public void onFilter(Filters filters) {
         Query query = mFireStore.collection("Products");

        // Category (equality filter)
        if (filters.hasCategory()) {
            query = query.whereEqualTo(Product.FIELD_CATEGORY, filters.getCategory());
        }

        // City (equality filter)
        if (filters.hasCity()) {
            query = query.whereEqualTo(Product.FIELD_CITY, filters.getCity());
        }

        // Price (equality filter)
        if (filters.hasPrice()) {
            query = query.whereEqualTo(Product.FIELD_PRICE, filters.getPrice());
        }
        // Sort by (orderBy with direction)
        if (filters.hasSortBy()) {
            query = query.orderBy(filters.getSortBy(), filters.getSortDirection());
        }

        // Limit items
        query = query.limit(LIMIT);

        Log.d("Query Info", query.toString());




        FirestoreRecyclerOptions<Product> response = new FirestoreRecyclerOptions.Builder<Product>()
                .setQuery(query,Product.class)
                .build();


        adapter = new FirestoreRecyclerAdapter<Product,ExploreViewholder>(response) {

            @Override
            public ExploreViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
                View view = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.recycler_view_explore_item, parent, false);
                return new ExploreViewholder(view);
            }

            @Override
            protected void onBindViewHolder(@NonNull ExploreViewholder holder, int position, @NonNull Product model) {
                holder.productName.setText(model.getProductName());
                holder.creatorName.setText(mUser.getDisplayName());
                holder.productDesc.setText(model.getProductDescription());
//                Glide.with(getContext())
//                        .load(model.getProductImageUrl())
//                        .into(holder.productImage);

            }


            @Override
            public void onError(FirebaseFirestoreException e) {
                Log.e("error", e.getMessage());
            }
        };

        adapter.notifyDataSetChanged();
        mRecycler.setAdapter(adapter);




    }

希望这会有所帮助..