React-select 在 React.js Redux Firebase 应用程序中输出格式错误的数组

React-select outputting a malformed array in a React.js Redux Firebase application

我有一个 React Redux 应用程序,它使用 npm 包 react-select 和 multi-select 片段。我的问题是它创建了一个我无法迭代的格式错误的数组。

this.state.typeOfFruit = [
   0: {label: "label 1", value: "apple"},
   1: {label: "label 2", value: "orange"},
   2: {label: "label 3", value: "banana"} 
]

我希望现在能够使用基本命令对其进行迭代,以开始收集正确的信息。

typeOfFruit.map((fruit) => console.log(fruit.value))

我试图找出如何访问格式错误的数组或将数组更改为我可以访问的内容,但认为我的问题需要更改为如何使用此技术创建一个好的数组。

下面的代码是整体代码的一部分,但它应该涵盖问题的所有部分。如果你看到任何明显的漏洞,请告诉我。

class FruitOrderForm extends Component {
   constructor(props) {
     super(props)
     this.state = {
       typeOfFuit: [],
     }
   }

const fruitOptions = [
   { value: 'apple', label: 'label 1' },
   { value: 'orange', label: 'label 2' },
   { value: 'banana', label: 'label 3' },
]

handleMultiSelectChange = (typeOfFruit) => {
   this.setState({ typeOfFruit });
}

onSubmit = (e) => {
   e.preventDefault();
   this.props.updateProfile(this.state)
   document.getElementById("fruitOrderForm").reset();
}

render() {
   this.state.typeOfFruit.map((fruit) => console.log(fruit.value))
   return (
      <div>
        <form id='fruitOrderForm' onSubmit={this.onSubmit}>
          < Select
            id='typeOfFruit'
            value={this.state.typeOfFruit}
            onChange={this.handleMultiSelectChange}
            options={fruitOptions }
            isMulti='true'
            isSearchable='true'
          />
          <button>Update</button>
        </form>
      </div>
   )
}
}

const mapStateToProps = (state, ownProps) => {
const profile = state.firebase.profile

return{
   profile: profile,
   auth: state.firebase.auth
} 
}

const mapDispatchToProps = (dispatch) => {
    return {
       updateProfile: (users) => dispatch(updateProfile(users)),
    }
}

export default compose(
   connect(mapStateToProps, mapDispatchToProps),
   firestoreConnect([{ collection: 'users'}]))(
FruitOrderForm)

然后去store redux action

export const updateProfile = (users) => {
   return (dispatch, getState, { getFirebase, getFirestore }) => {
      const firestore = getFirestore();
      const profile = getState().firebase.profile
      const userID = getState().firebase.auth.uid;
      firestore.collection('users').doc(userID).update({
         ...profile,
         typeOfConsulting: users.typeOfConsulting
      }).then(() => {
         dispatch({ type: 'UPDATED_PROFILE', profile });
         console.log('update successful')
      }).catch((err) => {
         dispatch({ type: 'UPDATE_PROFILE_ERROR', err });
         console.log('There was an error', err)
      })
   }
}

然后通过reducer

const businessProfileReducter = (state = initState, action) => {
   switch (action.type) {
      case 'CREATE_BUSINESS_PROFILE': 
         console.log('created business profile', action.businessProfile)
         return state;
      case 'CREATE_BUSINES_PROFILE_ERROR': 
         console.log('create business profile error', action.err);
         return state;
     default:
        return state;
   }
}

export default businessProfileReducter;

然后是root reducer

const rootReducer = combineReducers({
   auth: authReducer,
   businessProfile: businessProfileReducer,
   firestore: firestoreReducer,
   firebase: firebaseReducer
})

export default rootReducer

我希望由此输出的是一个我可以迭代的好数组。

this.state.typeOfFruit = [
   {label: "label 1", value: "apple"}
   {label: "label 2", value: "orange"}
   {label: "label 3", value: "banana"} 
]

看起来您可能实际上得到的是对象而不是数组(显示键的事实)。如果是这种情况,您可以使用以下方式对其进行迭代:

Object.keys(typeOfFruit).map((fruitId) => console.log(typeOfFruit[fruitId].value))

Object.values(typeOfFruit).map((fruit) => console.log(fruit.value))

好的,@smashed-potatoes。根据我们昨晚的谈话,我想通了。我没有在原来的地方执行 Object.values,而是将其移至 onSubmit 函数。我意识到我可以在将其发送到 Firebase 之前提取其中的各个值。我向 this.state 添加了一个新数组,然后在 onSubmit 函数中执行了一些操作以将其移动到正确的 this.state.typeOfConsulting 数组。请参阅下面的代码。它不是很漂亮,但是很管用!

class FruitOrderForm extends Component {
   constructor(props) {
     super(props)
     this.state = {
       typeOfFuit: [],
       interimTypeOfFruit: [],     
     }
   }

const fruitOptions = [
   { value: 'apple', label: 'label 1' },
   { value: 'orange', label: 'label 2' },
   { value: 'banana', label: 'label 3' },
]

handleMultiSelectChange = (typeOfFruit) => {
   this.setState({ typeOfFruit });
}

onSubmit = (e) => {
   e.preventDefault();
    // I'm setting typeOfFruit to an empty array because otherwise it continues to 
    // push the same values to the array that are already there.
    this.setState({
        typeOfFruit: []
    })
    // Then I'm pushing just the values from this.state.interimTypeOfFruit to the
    // proper this.state.typeOfFruit array that I can access like a regular array
    Object.values(this.state.interimTypeOfFruit).map((fruitType) => {
        this.state.typeOfFruit.push(fruitType.value)
    })
   this.props.updateProfile(this.state)
   document.getElementById("fruitOrderForm").reset();
}

render() {
   this.state.typeOfFruit.map((fruit) => console.log(fruit.value))
   return (
      <div>
        <form id='fruitOrderForm' onSubmit={this.onSubmit}>
          < Select
            id='typeOfFruit'
            value={this.state.typeOfFruit}
            onChange={this.handleMultiSelectChange}
            options={fruitOptions }
            isMulti='true'
            isSearchable='true'
          />
          <button>Update</button>
        </form>
      </div>
   )
}
}

const mapStateToProps = (state, ownProps) => {
const profile = state.firebase.profile

return{
   profile: profile,
   auth: state.firebase.auth
} 
}

const mapDispatchToProps = (dispatch) => {
    return {
       updateProfile: (users) => dispatch(updateProfile(users)),
    }
}

export default compose(
   connect(mapStateToProps, mapDispatchToProps),
   firestoreConnect([{ collection: 'users'}]))(
FruitOrderForm)

我不能给你的答案投赞成票,因为我还没有达到 15 分......不过我把它标记为正确答案。感谢您的帮助!