react编辑功能获取到的数据库数据不正确

新手上路,请多包涵

这是我写的一个监控系统,使用了react redux nodejs,按照数据库的priority排序,使用编辑功能时,可以正常编辑,显示也是正确的,但是第一次编辑之后再对同意条目编辑,发现在不刷新的情况下,ajax获取的数据是不争取的,指向的是重新排序前的那个数据,刷新之后又正常了,请问我该怎么解决这个问题。

这里用图片展示了过程:编辑过程

server.js 服务器入口

const Koa = require('koa')
const Router = require('koa-router')
const cors = require('koa2-cors')
const app = new Koa()
const router = new Router()
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import serversReducer from '../client/reducers/reducer'
import { renderToString } from 'react-dom/server'

const store = createStore(serversReducer)

const views = require('koa-views')
const co = require('co')
const convert = require('koa-convert')
const json = require('koa-json')
const onerror = require('koa-onerror')
const bodyparser = require('koa-bodyparser')
const logger = require('koa-logger')
const debug = require('debug')('koa2:server')
const path = require('path')
//const ReactDOMServer = require('react-dom/server')
const React = require('react')
const config = require('./config')
const routes = require('./routes')
const mongoose = require('mongoose')
const stateSchema = require('./models/State')
const mission = require('./models/port')
const port = process.env.PORT || config.port

import Main from '../client/containers/Main'

mongoose.connect('mongodb://127.0.0.1:27017/monitor', {
    useMongoClient: true
});
mongoose.Promise = global.Promise;

var State = mongoose.model("State", stateSchema);

// error handler
onerror(app)
// middlewares
app.use(bodyparser())
    .use(json())
    .use(logger())
    .use(cors())
    .use(require('koa-static')(__dirname + '/public'))
    .use(views(path.join(__dirname, '/views'), {
        options: {
            settings: {
                views: path.join(__dirname, 'views')
            }
        },
        map: {
            'ejs': 'ejs'
        },
        extension: 'ejs'
    }))
    .use(router.routes())
    .use(router.allowedMethods())

// logger
app.use(async(ctx, next) => {
    const start = new Date()
    await next()
    const ms = new Date() - start
    console.log(`${ctx.method} ${ctx.url} - $ms`)
})

router.get('/', async(ctx, next) => {

    const staticMarkup = await renderToString(
        <Provider store={store}>
            <Main />
        </Provider>
    )

    const preloadedState = store.getState();
    //console.log(preloadedState);

    await ctx.render('index', {
        reduxData: preloadedState,
        helloComponentMarkup: staticMarkup
    })
})

router.post('/show', async(ctx, next) => {

    ctx.body = 'ok';
    let newArray = [];

    await State.find({}, function(err, doc) {
        if (err) {
            return;
        }
        doc.forEach(function(element, index) {
            newArray.push(element);
        })
        ctx.response.body = JSON.stringify(newArray);
    }).sort({
        priority: 1
    })
})

router.post('/edit', async(ctx, next) => {

    ctx.body = 'ok'

    await State.update({
        _id: ctx.request.body.querymark
    }, {
        $set: {
            server_name: ctx.request.body.servername,
            jp_name: ctx.request.body.jpname,
            ip_address: ctx.request.body.ipaddress,
            port: ctx.request.body.port,
            priority: ctx.request.body.priority
        }
    }, function(err, doc) {
        if (err) {
            return;
        }
    })
})

router.post('/create', async(ctx, next) => {

    ctx.body = 'ok'

    await new State({
        server_name: ctx.request.body.servername,
        jp_name: ctx.request.body.jpname,
        ip_address: ctx.request.body.ipaddress,
        port: ctx.request.body.port,
        priority: ctx.request.body.priority
    }).save(function(err) {
        if (err)
            console.log(err.toString());
    })
})

router.post('/delete', async(ctx, next) => {

    ctx.body = 'ok'

    await State.remove({
        _id: ctx.request.body.id
    }, function(err, doc) {
        if (err) {
            return;
        }
    });
})

routes(router)

app.on('error', function(err, ctx) {
    console.log(err)
    logger.error('server error', err, ctx)
})

module.exports = app.listen(config.port, () => {
    console.log(`Listening on http://localhost:${config.port}`)
    console.log(__dirname);
})

ListContainer.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { Segment, Icon, Table, Modal, Button, Form } from 'semantic-ui-react'
const axios = require('axios')
export default class ListContainer extends Component {
    static propTypes = {
        post_data: PropTypes.object.isRequired,
        onDeleteServer: PropTypes.func,
        index: PropTypes.number
    }

    constructor(props) {
        super(props)
        this.state = ({
            servername: props.post_data.server_name,
            jpname: props.post_data.jp_name,
            ipaddress: props.post_data.ip_address,
            port: props.post_data.port,
            priority: props.post_data.priority
        })
    }

    handleDeleteServer() {
        if (this.props.onDeleteServer) {
            this.props.onDeleteServer(this.props.index)
        }
    }

    handleServerNameChange(event) {
        this.setState({
            servername: event.target.value
        })
    }

    handleJPNameChange(event) {
        this.setState({
            jpname: event.target.value
        })
    }

    handleIPChange(event) {
        this.setState({
            ipaddress: event.target.value
        })
    }

    handlePORTChange(event) {
        this.setState({
            port: event.target.value
        })
    }

    handlePriorityChange(event) {
        this.setState({
            priority: event.target.value
        })
    }

    handleSubmit() {
        axios.post('/edit', {
            querymark: this.props.post_data._id,
            servername: this.state.servername,
            jpname: this.state.jpname,
            ipaddress: this.state.ipaddress,
            port: this.state.port,
            priority: this.state.priority
        }).then((response) => {
            if (response.data.success === false) {
                alert("error");
            } else {
                window.location.reload();
            }
        }).catch(() => {
        })
        this.setState({
            open: false
        })
    }

    state = {
        open: false
    }

    show = (size, dimmer) => () => this.setState({
        size,
        dimmer,
        open: true
    })
    close = () => this.setState({
        open: false
    })

    render() {
        const {open, size, dimmer} = this.state
        const post_data = this.props.post_data
        var updated_time = (new Date(post_data.updated_at)).toLocaleString().replace('/T/', '').replace('/\../+', '')
        var state_color = (post_data.state == "green") ? "green" : "red"
        var icon_name = (post_data.state == "green") ? "smile" : "warning sign"
        return (
            <Table.Row>
                <Table.Cell><Icon name={icon_name} color={state_color}/></Table.Cell>
                <Table.Cell>{post_data.jp_name}</Table.Cell>
                <Table.Cell>{post_data.ip_address}</Table.Cell>
                <Table.Cell>{post_data.port}</Table.Cell>
                <Table.Cell>{updated_time}</Table.Cell>
                <Table.Cell>{post_data.priority}</Table.Cell>
                <Table.Cell>
                    <div>
                        <Icon link name='settings' color='purple' onClick={this.show('small', 'blurring')} />
                        <Modal size={size} dimmer={dimmer} open={open} onClose={this.close} closeIcon>
                        <Modal.Header>Edit</Modal.Header>             
                        <Modal.Content>
                            <Modal.Description>
                                <Form>
                                <Form.Group width='equal'>
                                <Form.Field>
                                    <label>Server Name</label>
                                    <input value={this.state.servername} onChange={this.handleServerNameChange.bind(this)} />
                                </Form.Field>
                                <Form.Field>
                                    <label>JP Name</label>
                                    <input value={this.state.jpname} onChange={this.handleJPNameChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                <Form.Group width='equal'>
                                <Form.Field>
                                    <label>IP Address</label>
                                    <input value={this.state.ipaddress} onChange={this.handleIPChange.bind(this)} />
                                </Form.Field>
                                <Form.Field>
                                    <label>Priority</label>
                                    <input value={this.state.priority} onChange={this.handlePriorityChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                <Form.Group>
                                <Form.Field>
                                    <label>Port</label>
                                    <input value={this.state.port} onChange={this.handlePORTChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                </Form>
                            </Modal.Description>
                        </Modal.Content>
                        <Modal.Actions>
                        <Button color='black' onClick={this.close}>
                            Nope
                        </Button>
                        <Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.handleSubmit.bind(this)} />
                        </Modal.Actions>
                        </Modal>
                    </div>
                </Table.Cell>
                <Table.Cell><Icon link name='trash' color='purple' onClick={this.handleDeleteServer.bind(this)} /></Table.Cell>
            </Table.Row>
        )
    }
}

SegmentContainer.js

import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { Container, Loader, Table, Grid, Icon, Button, Modal, Form } from 'semantic-ui-react'
import SegmentList from '../components/SegmentContainer'
import { initServers, deleteServer, editServer } from '../reducers/reducer'
import MenuFix from '../components/Menu'
const axios = require('axios')

class SegmentContainer extends Component {
    static propTypes = {
        servers: PropTypes.array,
        initServers: PropTypes.func,
        onDeleteServer: PropTypes.func,
    }

    constructor() {
        super()
        this._loadData()
    /*this.state = {
        servername: '',
        jpname: '',
        ipaddress: '',
        priority: ''
    }*/
    }

    componentDidMount() {
        if (this.timer) {
            clearInterval(this.timer)
        }
        this.timer = setInterval(() => {
            this._loadData()
        }, 3000)
    }

    componentWillUnmount() {
        clearInterval(this.timer)
    }

    _loadData() {
        let sorted_data = [];
        let posts_data = [];
        let response = axios.post('/show')
            .then((response) => {
                Object.keys(response.data).forEach(function(index) {
                    sorted_data.push(response.data[index]);
                })

                function _dataCompare(a, b) {
                    if (a.priority > b.priority)
                        return 1;
                    if (a.priority < b.priority)
                        return -1;
                    return 0;
                }

                sorted_data.forEach((item, index) => {
                    posts_data.push(item);
                })
                //posts_data.sort(_dataCompare);
                this.props.initServers(posts_data)
            }).catch(() => {
        })

    }

    handleDeleteServer(index) {
        const {servers} = this.props
        axios.post('/delete', {
            id: servers[index]._id
        }).then((response) => {
            if (response.data.success === false) {
                alert("error");
            } else {
                window.location.reload();
            }
        }).catch(() => {
        })
        if (this.props.onDeleteServer) {
            this.props.onDeleteServer(index)
        }
    }

    handleCreate(server) {
        axios.post('/create', {
            servername: this.state.servername,
            jpname: this.state.jpname,
            ipaddress: this.state.ipaddress,
            port: this.state.port,
            priority: this.state.priority
        }).then((response) => {
            if (response.data.success === false) {
                alert("error");
            } else {
                window.location.reload();
            }
        }).catch(() => {
        })
        this.setState({
            open: false
        })
        if (this.props.onAddServer) {
            this.props.onAddServer(server)
        }
    }

    handleServerNameChange(event) {
        this.setState({
            servername: event.target.value
        })
    }

    handleJPNameChange(event) {
        this.setState({
            jpname: event.target.value
        })
    }

    handleIPChange(event) {
        this.setState({
            ipaddress: event.target.value
        })
    }

    handlePORTChange(event) {
        this.setState({
            port: event.target.value
        })
    }

    handlePriorityChange(event) {
        this.setState({
            priority: event.target.value
        })
    }

    state = {
        open: false
    }
    show = (size, dimmer) => () => this.setState({
        size,
        dimmer,
        open: true
    })

    close = () => this.setState({
        open: false
    })

    render() {
        const {open, size, dimmer} = this.state
        return (
            <Grid>
            <MenuFix /> 
            <Container style = {{
                marginTop: '6em'
            }}>
                <Table unstackable>
                    <Table.Header>
                        <Table.Row>
                        <Table.HeaderCell colSpan='8'>
                            <Button basic color='violet' floated='right' icon labelPosition='left' primary size='tiny' onClick={this.show('small', 'blurring')}>
                                <Icon link color='violet' name='add' />Add
                            </Button>
                            <Modal size={size} dimmer={dimmer} open={open} onClose={this.close} closeIcon>
                            <Modal.Header>Add</Modal.Header>
                            <Modal.Content>
                                <Modal.Description>
                                    <Form>
                                <Form.Group width='equal'>
                                <Form.Field>
                                    <label>Server Name</label>
                                    <input value={this.state.servername} onChange={this.handleServerNameChange.bind(this)} />
                                </Form.Field>
                                <Form.Field>
                                    <label>JP Name</label>
                                    <input value={this.state.jpname} onChange={this.handleJPNameChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                <Form.Group width='equal'>
                                <Form.Field>
                                    <label>IP Address</label>
                                    <input value={this.state.ipaddress} onChange={this.handleIPChange.bind(this)} />
                                </Form.Field>
                                <Form.Field>
                                    <label>Priority</label>
                                    <input value={this.state.priority} onChange={this.handlePriorityChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                <Form.Group>
                                <Form.Field>
                                    <label>Port</label>
                                    <input value={this.state.port} onChange={this.handlePORTChange.bind(this)} />
                                </Form.Field>
                                </Form.Group>
                                </Form>
                                </Modal.Description>
                            </Modal.Content>
                            <Modal.Actions>
                                <Button color='black' onClick={this.close}>
                                    Nope
                                </Button>
                                <Button positive icon='checkmark' labelPosition='right' content="Submit" onClick={this.handleCreate.bind(this)} />
                            </Modal.Actions>
                            </Modal>
                        </Table.HeaderCell>
                        </Table.Row>
                        <Table.Row>
                            <Table.HeaderCell>State<Loader active inline size='small' /></Table.HeaderCell>
                            <Table.HeaderCell>Server Name</Table.HeaderCell>
                            <Table.HeaderCell>IP Address</Table.HeaderCell>
                            <Table.HeaderCell>Port</Table.HeaderCell>
                            <Table.HeaderCell>Updated</Table.HeaderCell>
                            <Table.HeaderCell>Priority</Table.HeaderCell>
                            <Table.HeaderCell>Edit</Table.HeaderCell>
                            <Table.HeaderCell>Delete</Table.HeaderCell>
                        </Table.Row>
                    </Table.Header>
                    <SegmentList posts_data = {this.props.servers} onDeleteServer={this.handleDeleteServer.bind(this)} />
                </Table>
            </Container>
            </Grid>
        )
    }
}

const mapStateToProps = (state) => {
    return {
        servers: state.servers
    }
}

const mapDispatchToProps = (dispatch) => {
    return {
        initServers: (servers) => {
            dispatch(initServers(servers))
        },
        onDeleteServer: (serverIndex) => {
            dispatch(deleteServer(serverIndex))
        },
        onEditServer: (serverIndex) => {
            dispatch(editServer(serverIndex))
        },
        onAddServer: (server) => {
            dispatch(addServer(server))
        }
    }
}

export default connect(
    mapStateToProps,
    mapDispatchToProps
)(SegmentContainer)
阅读 1.9k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题