首页 > 解决方案 > 表单提交后重新渲染组件

问题描述

我正在使用redux创建一个react-native应用程序。我有两个屏幕,第一个是主屏幕,所有项目列表都在那里,第二个是表单屏幕,其中会有一个表单。当用户通过单击提交按钮提交表单时,用户应该被重定向到主屏幕,并且那时主屏幕应该重新呈现以前的状态和提交的新状态集。

我已经添加了我的文件,请看一下。在我进入主屏幕时提交表单后,它没有显示我添加的新值,要查看我添加的内容,我必须从终端手动刷新应用程序,然后我才能看到具有的新值已添加,所以我应该怎么做才能在不从终端手动刷新应用程序的情况下获得附加值

bookAction.js

import {
   FETCHING_BOOKS_REQUEST,
   FETCHING_BOOKS_SUCCESS,
   FETCHING_BOOKS_FAILURE,
   CREATE_BOOKS_REQUEST
} from "./types";
import axios from "axios";


export const fetchingBooksRequest = () => ({
   type:FETCHING_BOOKS_REQUEST
});

export const fetchingBooksSuccess = (data) => ({
   type:FETCHING_BOOKS_SUCCESS,
   payload:data
});


export const fetchingBooksFailure = (error) => ({
   type:FETCHING_BOOKS_FAILURE,
   payload:error
});


export const fetchBooks = () => {
   return (dispatch) => {
      dispatch(fetchingBooksRequest())
        axios.get("http://IpAddress:3000/api/Books")
            .then((response)=>{
                dispatch(fetchingBooksSuccess(response.data))
                // console.log(response.data)
            })
            .catch ((error) =>  {
                dispatch(fetchingBooksFailure(error))
            });
      }
   }

AddBookAction.js

import {
  TITLE_ADD,
  DESCRIPTION_ADD,
  ADD_BOOKS,
  ADD_BOOKS_SUCCESS,
  ADD_BOOKS_FAILURE
} from "./types";
import {Actions} from "react-native-router-flux"



export const titleAdd = (text) => {
   return{
      type:TITLE_ADD,
      payload:text
   };
};

export const descriptionAdd = (text) => {
    return{
       type:DESCRIPTION_ADD,
       payload:text
   };
};

export const createBooks = ({title,description}) => {
   return (dispatch) => {
     dispatch({
        type:ADD_BOOKS
    })
    fetch("http://IPAddress:3000/api/Books",{
        method:"POST",
        headers:{
            "content-type":"application/json"
        },
        body:JSON.stringify({title,description})
     })
      .then(res=>res.json())
      .then(() => {
         dispatch({
             type:ADD_BOOKS_SUCCESS

         });
     })
     .catch((error) => {
         console.log(error)
          dispatch({
            type:ADD_BOOKS_FAILURE
         })
     })
    }
   }

BookReducer.js

import {
  FETCHING_BOOKS_REQUEST,
  FETCHING_BOOKS_SUCCESS,
  FETCHING_BOOKS_FAILURE,
} from "../actions/types";


 const INITIAL_STATE = { 
   books:[],
   loading:false,
   errorMessage:""
};


 export default (state = INITIAL_STATE, action)=>{
    console.log(action);
      switch(action.type){
         case FETCHING_BOOKS_REQUEST:
           return { ...state, loading:true };
         case FETCHING_BOOKS_SUCCESS:
           return { ...state, loading:false, books:action.payload };
         case FETCHING_BOOKS_FAILURE:
           return { ...state, loading:true, errorMessage:"error occurs" };
        default:
           return state;
    }
 };

AddbookReducer.js

import {
   TITLE_ADD,
   DESCRIPTION_ADD,
   ADD_BOOKS,
   ADD_BOOKS_SUCCESS,
   ADD_BOOKS_FAILURE
} from "../actions/types";


 const INITIAL_STATE = { 
    title:"",
    description:"",
    error:""
 };


  export default (state = INITIAL_STATE, action)=>{
     console.log(action);
      switch(action.type){
        case TITLE_ADD:
          return { ...state, title:action.payload  };
        case DESCRIPTION_ADD:
          return { ...state, description:action.payload  };
        case ADD_BOOKS:
          return { ...state, error:""  };
        case ADD_BOOKS_SUCCESS:
          return { 
            ...state, 
            error:"", 
            title:"", 
            description:""  
         };
        case ADD_BOOKS_FAILURE:
          return { 
            ...state , 
            error:"Can't post data error occur",
            title:"",
            description:""
         }
       default:
         return state;
     }
 };

AddBook.js(表单组件)

import React, { Component } from 'react';
import { 
  View, 
  Text,
  StyleSheet,
  KeyboardAvoidingView,
  ScrollView,
  TextInput,
  TouchableOpacity
} from 'react-native';
import { connect } from 'react-redux';
import {createBooks,titleAdd,descriptionAdd} from 
"../redux/actions/AddBookActions";
import { Actions } from 'react-native-router-flux';

class AddBooks extends Component {


 static navigationOptions = ({navigation}) => ({
     title: 'Add books',
     headerTintColor: '#ffffff',
     headerStyle: {
      backgroundColor: '#2F95D6',
      borderBottomColor: '#ffffff',
      borderBottomWidth: 3,

    },
    headerTitleStyle: {
      fontSize: 18,
    },

});





   onTitleAdd(text){
    this.props.titleAdd(text)
   }

   onDescriptionAdd(text){
    this.props.descriptionAdd(text)
   }

    onButtonPress({navigation}) {
      const { title, description  } = this.props;

    this.props.createBooks({  title, description });

    this.onFormSubmit(this.props)
   }

    componentWillReceiveProps(nextProps) {
      this.onFormSubmit(nextProps)
    }

   onFormSubmit({navigation}){
    navigation.navigate("AllBooks")
   }


  render() {
    return (
     <View style={styles.container}>
      <KeyboardAvoidingView 
      behavior="padding" 
      style={styles.container}>
      <ScrollView>
       <View>
         <TextInput style={styles.textInput} 
                  placeholder="Title"
                  placeholderTextColor="black"
                  underlineColorAndroid="rgba(0,0,0,0)"
                  onChangeText={this.onTitleAdd.bind(this)}
                  value={this.props.title}
         />
       </View>
       <View>
         <TextInput style={styles.textInput} 
                    placeholder="Description"
                    placeholderTextColor="black"
                    underlineColorAndroid="rgba(0,0,0,0)"
                    onChangeText={this.onDescriptionAdd.bind(this)}
                    value={this.props.description}
         />
       </View>
       <TouchableOpacity 
        style={styles.button}
       onPress={this.onButtonPress.bind(this)}
       >
        <Text style={styles.buttonText}>
            Submit 
        </Text>    
       </TouchableOpacity>

      </ScrollView>
     </KeyboardAvoidingView>
    </View>
   );
  }
 }

mapStateToProps  = ({addBookReducers}) => {
  const { title,description } = addBookReducers;

  return {
   title,
   description
  }
 }

 export default connect(mapStateToProps,{
    titleAdd,
    descriptionAdd,
    createBooks,

 })(AddBooks)

const styles = StyleSheet.create({
  container:{
    backgroundColor:"#EBF5FB",
    flex:1
  },
  textInput:{
    marginTop: 10,
    fontSize:20,
    height:50,
    borderColor:"black", 
    borderWidth: 1,
    width:"100%"
 },
 button:{
  width:"100%",
  backgroundColor: "#19B5FE",
  marginVertical: 10,
  paddingVertical: 16,
  borderRadius: 30,
 },
 buttonText:{
    fontSize:16,
    fontWeight:"500",
    textAlign:"center",
    color:"black"

  },
})

AllBooks.js(主屏幕组件)

          import React, { Component } from 'react';
      import { 
        View, 
        Text, 
        StyleSheet, 
        ScrollView, 
        KeyboardAvoidingView,
        ActivityIndicator,
        TouchableOpacity
      } from 'react-native';
      import { fetchBooks } from "../redux/actions/BooksActions";
      import { connect } from "react-redux";
      import {PropTypes} from "prop-types";
      import Icon from "react-native-vector-icons/FontAwesome"

      class AllBooks extends Component {

        componentWillMount() {
          this.props.fetchBooks()
        }




        render() {
          const { error, loading, Books } = this.props;
          if (error) {
            return(
              <View style={ styles.container }>
                <Text>{error}</Text>
              </View>
            )
          }
          if(loading){
            return(
              <View style={ styles.container }>
                <ActivityIndicator size={50} color="blue"/>
              </View>
            )
          };

          return (

            <View style={styles.scrollViewWrapper}>
              <ScrollView style={styles.scrollView}>

                <View style={styles.mainView}>
                  {Books.map((book) =>
                    <TouchableOpacity
                    key={book._id}
                    style={styles.paticularView}
                    >
                      <Text style={styles.text}>{book.title}</Text>
                    </TouchableOpacity>
                  )}
                </View>
              </ScrollView>
            </View> 

          );
        }
      };

      AllBooks.propTypes = {
        fetchBooks:PropTypes.func.isRequired,
        Books:PropTypes.array.isRequired
      }


      mapStateToProps = (state) => {
        return { 
          Books:state.bookReducers.books,
          error:state.bookReducers.errorMessage,
          loading:state.bookReducers.loading
        }
      }


      export default connect(mapStateToProps, {fetchBooks} )(AllBooks);

      const styles = StyleSheet.create({
          scrollViewWrapper:{
            flex:1,
          },
          scrollView:{
            paddingTop: 20,
            flex:1
          },
          mainView:{
            height:"100%",
          },
          paticularView:{
            height:80,
            borderWidth: 2,
            borderRadius: 2,
            borderColor: '#E5E7E9',
            borderBottomWidth: 0,
            shadowColor: '#000',
            shadowOffset: { width: 0, height: 3 },
            shadowOpacity: 0.8,
            shadowRadius: 2,
            elevation: 1,
            marginLeft: 5,
            marginRight: 5,
            marginTop: 10,

          },
          text:{
            fontSize:18,
            marginLeft:5,
            marginTop:5
          }
      });

标签: react-nativereduxreact-navigation

解决方案


只需使用 componentWillRecieveProps,只要 props 发生一些变化,就会触发此回调函数,在您想要像这样更新 List 的主组件中使用它

componentWillRecieveProps(nextProps){
  if(!isFetching && this.props.data !== nextProps.data) // or implement your preferred condition
    this.setState({UpdateList: this.props.data}) // this would call the render function
  }
}

您还可以在返回时从子组件显式调用主组件函数,如下所示


推荐阅读