Javascript 在React/Redux中更改url
我正在尝试用React和Redux(DVA)构建一个应用程序。它使用Ant.Design作为主要框架。我试图在用户点击一个按钮时更改URL,很明显,将URL更改“绑定”到一个动作,这样,如果用户直接访问该URL,他就可以得到他想要的 现在,这是我在我的组件中的一个函数Javascript 在React/Redux中更改url,javascript,reactjs,redux,react-router,antd,Javascript,Reactjs,Redux,React Router,Antd,我正在尝试用React和Redux(DVA)构建一个应用程序。它使用Ant.Design作为主要框架。我试图在用户点击一个按钮时更改URL,很明显,将URL更改“绑定”到一个动作,这样,如果用户直接访问该URL,他就可以得到他想要的 现在,这是我在我的组件中的一个函数 const { dispatch, match } = this.props; dispatch(routerRedux.push('/f/' + record.id)); 这是我唯一能制作的东西。它正确地更改了url,但没有将
const { dispatch, match } = this.props;
dispatch(routerRedux.push('/f/' + record.id));
这是我唯一能制作的东西。它正确地更改了url,但没有将url与特定行为绑定,使其完全无用
如何使用操作链接URL 如果希望基于URL触发操作,则需要使用
react router
路由一个组件,然后该组件执行所需操作。在这种情况下,最好访问其他URL,从浏览器的历史记录中删除操作URL
典型的路由器定义可能如下所示(摘自):
注意使用
replace
代替push
。这意味着,当用户访问此URL时,他们的操作将被执行,并最终获得/success
。但如果他们单击“上一步”按钮,他们将不会再次访问此URL并再次运行操作。出于隐私原因,我无法将代码放在Codepen上。但这里有一个摘录:
路由器.js
...
},
'/users': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
'/f/:userID': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
...
js(包含LeftPanel和RightPanel的主要组件)
import React,{PureComponent}来自'React';
从“dva”导入{connect};
从“antd”导入{Row,Col,Card,List,Divider,Badge,Select,Radio,Input,Popover,Button,Table,Spin};
从“/RightPanel”导入RightPanel;
从“/LeftPanel”导入LeftPanel;
从“dva/路由器”导入{routerRedux,Route,Switch};
导入'font-awesome/css/font-awesome.min.css';
从“反应淡入”导入淡入;
@连接(({rule,loading})=>({rule,loading:loading.models.rule}))
导出默认类用户扩展React.Component{
建造师(道具){
超级(道具)
此.state={
所选用户:[],
defaultView:true,
isLoadingNow:错误,
选定的箭头键:[],
makeEmpty:false,
搜索结果:[]
}
}
选择行=(记录)=>{
const{dispatch,match}=this.props;
分派(routerRedux.replace({pathname:'/f/'+record.id}));
this.setState({isLoadingNow:true,selectedRowKeys:record.key})
设置超时(()=>{
这是我的国家({
isLoadingNow:错误,
defaultView:false,
所选用户:记录
})
}, 75)
}
componentDidMount(){
const{dispatch,match}=this.props;
派遣({
键入:“规则/获取”
});
if(match.params.userID==未定义){
//无所事事
}else if(match.params.userID){
var result=this.props.rule.data.list.filter(函数(obj){
返回obj.id==match.params.userID;
});
this.selectRow.bind(此,结果[0])
}
}
render(){
const{selectedRowKeys}=this.state;
常量行选择={
选择的箭头键,
类型:“收音机”
};
const{rule:{data},load}=this.props;
返回(
);
}
}
leftPanel.js(负责显示链接列表,用户将在其中单击一个链接,这将做两件事:-相应地更改url
-在RightPanel.js上显示特定数据)
从“React”导入React;
从“antd”导入{表,卡};
从“./index.less”导入样式;
//导入'font-awesome/css/font-awesome.min.css';
从“antd”导入{Row,Col,List,Divider,Badge,Select,Radio,Input,Popover,Button};
var力矩=要求的(‘力矩’);
类LeftPanel扩展了React.Component{
建造师(道具){
超级(道具)
此.state={
所选行索引:未定义
}
}
HandleChangeStyleOnElectrow(索引){
这是我的国家({
所选行索引:索引
},console.log(this.state.selected_row_index))
}
可美化(原始数据){
var-prettyRows=[];
原始数据.map((项目,索引)=>
推(
{item.user_name}{item.user_age}
{矩(item.user\u color).format('HH:MM')}·{矩(item.user\u order).format('HH:MM')}
{item.user_family}
{力矩(item.user_height).format('MMMM D')}
{(item.status==“进行中”)?:}
)
);
返回窗口;
}
render(){
const stylesSelectedRow={“背景”:“rgba(155155,0.05)”,“盒影”:“0 0 5px 0#4A90E2”,“变换”:“比例(1.01)”;
const{dataSource}=this.props;
返回(
{数据源&&
({this.state.selected_row_index==index?null:this.props.selectRow(this.props.dataSource[index]);this.handlechangestyleonsetrow(index)}style={this.state.selected_row_index==index?stylesSelectedRow:null}className={styles.userRows}>{item}
/>
}
)
}
}
导出默认左面板;
最后是RightPanel.js,它负责监听URL或
<Route path="/f/:recordId" component={MyActionComponent}/>
import { connect } from 'react-redux';
import { replace } from 'react-router-redux';
const mapDispatchToProps = (dispatch: Dispatch) => ({
visitNextLocation: () => dispatch(replace('/success')),
myAction: (recordId) => dispatch(myAction(recordId)),
});
const withDispatch = connect(null, mapDispatchToProps);
class MyActionComponent extends Component {
props: {
match: {
params: {
recordId: string,
}
},
redirectToLogin: () => void,
myAction: string => void,
};
componentWillMount() {
const recordId = this.props.match.params.recordId;
if (recordId) {
this.props.myAction(token);
this.props.visitNextLocation();
}
}
render() {
return null;
}
}
...
},
'/users': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
'/f/:userID': {
component: dynamicWrapper(app, ['rule'], () => import('../routes/users')),
},
...
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Row, Col, Card, List, Divider, Badge, Select, Radio, Input, Popover, Button, Table, Spin } from 'antd';
import RightPanel from './RightPanel';
import LeftPanel from './LeftPanel';
import { routerRedux, Route, Switch } from 'dva/router';
import 'font-awesome/css/font-awesome.min.css';
import FadeIn from 'react-fade-in';
@connect(({ rule, loading }) => ({rule, loading: loading.models.rule }))
export default class Users extends React.Component {
constructor(props) {
super(props)
this.state = {
selected_user: [],
defaultView: true,
isLoadingNow: false,
selectedRowKeys: [],
makeEmpty: false,
searchRes: []
}
}
selectRow = (record) => {
const { dispatch, match } = this.props;
dispatch(routerRedux.replace({ pathname: '/f/' + record.id }));
this.setState({isLoadingNow: true, selectedRowKeys: record.key})
setTimeout(() => {
this.setState({
isLoadingNow: false,
defaultView: false,
selected_user: record
})
}, 75)
}
componentDidMount() {
const { dispatch, match } = this.props;
dispatch({
type: 'rule/fetch'
});
if (match.params.userID == undefined) {
// do nothing
} else if (match.params.userID) {
var result = this.props.rule.data.list.filter(function( obj ) {
return obj.id == match.params.userID;
});
this.selectRow.bind(this, result[0])
}
}
render() {
const { selectedRowKeys } = this.state;
const rowSelection = {
selectedRowKeys,
type:"radio"
};
const { rule: { data }, loading } = this.props;
return (<div>
<LeftPanel
rowSelection={rowSelection}
dataSource={this.state.makeEmpty ? this.state.searchRes : this.props.rule.data.list}
selectRow={this.selectRow}
loadingStatus={loading}
/>
<RightPanel
selected_user={this.state.selected_user}
is_default={this.state.defaultView}
loading={this.state.isLoadingNow}
/>
</div>);
}
}
import React from 'react';
import { Table, Card } from 'antd';
import styles from './index.less';
// import 'font-awesome/css/font-awesome.min.css';
import { Row, Col, List, Divider, Badge, Select, Radio, Input, Popover, Button } from 'antd';
var moment = require('moment');
class LeftPanel extends React.Component {
constructor(props) {
super(props)
this.state = {
selected_row_index: undefined
}
}
handleChangeStyleOnSelectRow(index) {
this.setState({
selected_row_index: index
}, console.log(this.state.selected_row_index))
}
prettifyForTable(raw_data) {
var prettyRows = [];
raw_data.map((item,index) =>
prettyRows.push(
<div style={{"width": "100%"}}>
<Row style={{ "align-items": "center"}} type="flex" justify="space-between">
<Col span={10}>
<div style={{"font-size": "15px", "text-align": "center"}}>
{item.user_name} <i style={{"color": "rgba(0, 0, 0, 0.25)", "margin": "0 10px", "transform": "rotate(45deg)"}} className="fa fa-plane"> </i> {item.user_age}
<div style={{"font-size": "12px", "color": "grey"}}> {moment(item.user_color).format('HH:MM')} · {moment(item.user_order).format('HH:MM')} </div>
</div>
</Col>
<Col span={3}>
<div style={{"text-align": "right", "text-align": "center"}}>
{item.user_family}
</div>
</Col>
<Col span={6}>
<div style={{"text-align": "right", "text-align": "center"}}>
{moment(item.user_height).format('MMMM D')}
</div>
</Col>
<Col span={3}>
<div style={{"text-align": "center"}}>
{(item.status == "in_progress") ? <div> <Badge style={{"padding-right": "25px"}} status="processing"/></div> : <div style={{"text-align": "center"}}> <Badge style={{"padding-right": "25px"}} status="default"/></div>}
</div>
</Col>
</Row>
</div>
)
);
return prettyRows;
}
render() {
const stylesSelectedRow = { "background": "rgba(155,155,155,0.05)", "box-shadow": "0 0 5px 0 #4A90E2", "transform": "scale(1.01)"};
const { dataSource } = this.props;
return(
<div>
{dataSource &&
<Card bordered={false} loading={this.props.loadingStatus} className={styles.userRows} bodyStyle={{"padding": "0 15px"}}>
<List
size="small"
bordered={false}
dataSource={this.prettifyForTable(dataSource)}
renderItem={(item, index) => (<List.Item onClick={() => {this.state.selected_row_index == index ? null : this.props.selectRow(this.props.dataSource[index]); this.handleChangeStyleOnSelectRow(index)}} style={this.state.selected_row_index == index ? stylesSelectedRow : null} className={styles.userRows}>{item}</List.Item>)}
/>
</Card>
}
</div>
)
}
}
export default LeftPanel;
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import infopng from '../../../assets/info.svg';
import TabInformations from './TabInformations.js';
import TabFamily from './TabFamily.js';
import TabProblems from './TabProblems.js';
import { Tabs, Button, Spin, Icon, Table, Pagination, Card, Col, Row, Spinner, Badge } from 'antd';
const TabPane = Tabs.TabPane;
import 'font-awesome/css/font-awesome.min.css';
import WindowSizeListener from 'react-window-size-listener'
import FadeIn from 'react-fade-in';
export default class RightPanel extends Component {
render() {
if (this.props.loading) {
return(
<div>
<Spin
indicator={<Icon type="loading" style={{ fontSize: 24 }} spin />}
src="http://web.gndu.ac.in/DepartmentProfile/images/spinner.gif"
/>
</div>
);
} else if (this.props.is_default) {
return(
<div style={{"margin-top": "64px", "margin-right": "10px", "text-align": "center", "height": "90vh", "display": "flex", "align-items": "center", "justify-content": "center"}}>
<div>
<img src={infopng} style={{"height": "155px"}} />
<p style={{"color": "#8e8e8e"}}> select a user on the <br/> left-hand side... </p>
</div>
</div>
);
} else {
return (
<FadeIn>
<Card bodyStyle={{"padding": "0"}} style={{"background-color": "white", "height":"90vh", "padding": "20px", "box-shadow": "rgba(0, 21, 41, 0.1) 0px 0px 6px", "opacity": "1", "transition": "background 0.6s", "border-radius": "2px", "margin": "10px 10px 0 0px", "margin-top": "64px"}}>
<Tabs defaultActiveKey="1" style={{"text-align": "center", "padding": "0 15px"}}>
<TabPane tab="General" key="1">
<TabInformations
selected_user={this.props.selected_user}
/>
</TabPane>
<TabPane tab="Servicing" key="2">
<TabFamily
selected_user={this.props.selected_user}
/>
</TabPane>
<TabPane tab={<div>Defect(s)<Badge showZero count={0} style={{ backgroundColor: '#fff', color: '#999', boxShadow: '0 0 0 1px #d9d9d9 inset', "margin-left": "10px" }} /></div>} key="3">
<TabProblems />
</TabPane>
</Tabs>
</Card>
</FadeIn>
);
}
}
}