我有以下代码。 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}/>
}/>
但是,我不确定这是正确的做法吗?
答案 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);
}
希望这会有所帮助..