How do I take an object from one file and place it in an array element of another in my React Native app?

huangapple go评论59阅读模式
英文:

How do I take an object from one file and place it in an array element of another in my React Native app?

问题

以下是代码部分的中文翻译:

我有一个运动应用程序,我正在尝试选择要记录在锻炼中的运动。根据我目前的情况,我生成了一个可以选择肌肉类别的列表,然后显示要添加到锻炼中的运动列表。我希望特定肌肉类别的options数组可以从一个名为AbsExerciseList.js的单独.js文件生成。

// AbsExerciseList.js
const abList = [
    { id: '1', label: '仰卧起坐' },
    { id: '2', label: '抬腿' }
]

export default abList

然后,supOptions属性(在选择类别后生成的运动列表)将出现。如何将来自AbsExerciseList.js的对象插入到subOptions对象/数组中(特别是id: '1',label: 'abs')?

我想对所有其他肌肉类别执行相同的操作。

// New WorkourtList.js
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, FlatList } from 'react-native';
import abList from './exercises/AbsExerciseList';

const MyDropDown = () => {
  const [selectedOption, setSelectedOption] = useState(null);
  const [showOptions, setShowOptions] = useState(false);
  const [options, setOptions] = useState([
    {
      id: '1',
      label: '腹部',
      subOptions: [
       // 在这里放置来自AbsExerciseList.js的abList
      ]
    },
    {
      id: '2',
      label: '二头肌',
      subOptions: [
        { id: '1', label: '上斜杠杠弯举' },
        { id: '2', label: '弯杠杠弯举' },
        { id: '3', label: '交替哑铃弯举' }
      }
    }
    //... 未列出的其他肌肉类别
  });

  const handleOptionSelect = (option) => {
    setSelectedOption(option);
    setShowOptions(false);
  };

  const renderOption = ({ item }) => (
    <TouchableOpacity style={{ padding: 10 }} onPress={() => handleOptionSelect(item)}>
      <Text>{item.label}</Text>
    </TouchableOpacity>
  );

  const renderSubOption = ({ item }) => (
    <TouchableOpacity style={{ padding: 10 }}>
      <Text>{item.label}</Text>
    </TouchableOpacity>
  );

  return (
    <View>
      <TouchableOpacity onPress={() => setShowOptions(!showOptions)}>
        <Text>{selectedOption ? selectedOption.label : '选择一个类别'}</Text>
      </TouchableOpacity>
      {showOptions && (
        <FlatList
          data={options}
          renderItem={renderOption}
          keyExtractor={(item) => item.id}
        />
      )}
      {selectedOption && (
        <FlatList
          data={selectedOption.subOptions}
          renderItem={renderSubOption}
          keyExtractor={(item) => item.id}
        />
      )}
    </View>
  );
};

export default MyDropDown;

我尝试在useState()内使用map函数,但遇到了“警告:列表中的每个子项应具有唯一的“key”属性”。

我不确定是否需要在useState()之外创建一个单独的函数或使用不同的React钩子。

英文:

I have an excersise app which I am trying to select exercises that are to be recorded for a workout. For what I have so far, I generate a list which can select a muscle category which then displays a list of excersises to be added to the workout. I would like the the options array of a specific muscle category to be generated from a seperate .js file of said category (AbsExerciseList.js)

//AbsExerciseList.js
const abList = [
{ id: &#39;1&#39;, label: &#39;Crunches&#39; }, 
{ id: &#39;2&#39;, label: &#39;Leg Raises&#39; } 
]
export default abList

I then have the supOptions property - which is the list of exercises generated after the category is selected - appear. How would I take the object from AbsExerciseList.js and insert it to the subOptions object/array (specifically for the id: '1' , label: 'abs') element?

I would like to do the same for all other muscle categories as well.

//New WorkourtList.js
import React, { useState } from &#39;react&#39;;
import { View, Text, TouchableOpacity, FlatList } from &#39;react-native&#39;;
import abList from &#39;./exercises/AbsExerciseList&#39;;
const MyDropDown = () =&gt; {
const [selectedOption, setSelectedOption] = useState(null);
const [showOptions, setShowOptions] = useState(false);
const [options, setOptions] = useState([
{
id: &#39;1&#39;,
label: &#39;Abs&#39;,
subOptions: [
//Place abList from AbsExerciseList.js here
]
},
{
id: &#39;2&#39;,
label: &#39;Biceps&#39;,
subOptions: [
{ id: &#39;1&#39;, label: &#39;Preacher Curl&#39; }, 
{ id: &#39;2&#39;, label: &#39;EZ-Bar Curl&#39; },
{ id: &#39;3&#39;, label: &#39;Alternating Dumbell Curl&#39; }
]
}
//... rest of muscle categories not listed
]);
const handleOptionSelect = (option) =&gt; {
setSelectedOption(option);
setShowOptions(false);
};
const renderOption = ({ item }) =&gt; (
&lt;TouchableOpacity style={{ padding: 10 }} onPress={() =&gt; handleOptionSelect(item)}&gt;
&lt;Text&gt;{item.label}&lt;/Text&gt;
&lt;/TouchableOpacity&gt;
);
const renderSubOption = ({ item }) =&gt; (
&lt;TouchableOpacity style={{ padding: 10 }}&gt;
&lt;Text&gt;{item.label}&lt;/Text&gt;
&lt;/TouchableOpacity&gt;
);
return (
&lt;View&gt;
&lt;TouchableOpacity onPress={() =&gt; setShowOptions(!showOptions)}&gt;
&lt;Text&gt;{selectedOption ? selectedOption.label : &#39;Select a Category&#39;}&lt;/Text&gt;
&lt;/TouchableOpacity&gt;
{showOptions &amp;&amp; (
&lt;FlatList
data={options}
renderItem={renderOption}
keyExtractor={(item) =&gt; item.id}
/&gt;
)}
{selectedOption &amp;&amp; (
&lt;FlatList
data={selectedOption.subOptions}
renderItem={renderSubOption}
keyExtractor={(item) =&gt; item.id}
/&gt;
)}
&lt;/View&gt;
);
};
export default MyDropDown;

I have tried using the map function within the useState() however i am met with, "Warning: Each child in a list should have a unique "key" prop."

I am not sure if I need to create a seperate function outside of useState() or use a different React hook.

答案1

得分: 1

以下是翻译好的部分:

如果您将所有子选项分开保存,那么它可能如下所示:

const abList = [
  { id: "1", label: "Crunches" },
  { id: "2", label: "Leg Raises" }
];

const bicepsList = [
  { id: "1", label: "Preacher Curl" },
  { id: "2", label: "EZ-Bar Curl" },
  { id: "3", label: "Alternating Dumbell Curl" }
];

然后在您的功能组件中,由于您不更新初始的 "options" 状态,您只需更改 "selectedOption" 状态并将子选项附加到相应的数组中。

只需像这样更改选择处理程序:

const handleOptionSelect = (option) => {
    switch (option.id) {
      case "1": {
        setSelectedOption({
          ...option,
          subOptions: option.subOptions.concat(abList)
        });
        break;
      }
      case "2": {
        setSelectedOption({
          ...option,
          subOptions: option.subOptions.concat(bicepsList)
        });
        break;
      }
      default: {
        setSelectedOption({
          ...option,
          subOptions: []
        });
        break;
      }
    }

    setShowOptions(false);
  };

option.subOptions.concat(anyList) 的好处是您可以从 "options" 状态中已经设置默认的练习,并追加更多的练习。

英文:

If you save all sub Options seperate, then it could look like this:

const abList = [
{ id: &quot;1&quot;, label: &quot;Crunches&quot; },
{ id: &quot;2&quot;, label: &quot;Leg Raises&quot; }
];
const bicepsList = [
{ id: &quot;1&quot;, label: &quot;Preacher Curl&quot; },
{ id: &quot;2&quot;, label: &quot;EZ-Bar Curl&quot; },
{ id: &quot;3&quot;, label: &quot;Alternating Dumbell Curl&quot; }
];

Then in your functional component, since you are not updating your initial "options" state, you can just alter your "selectedOption" state and append sub Otions into respective array.

Just alter the select handler like this:

const handleOptionSelect = (option) =&gt; {
switch (option.id) {
case &quot;1&quot;: {
setSelectedOption({
...option,
subOptions: option.subOptions.concat(abList)
});
break;
}
case &quot;2&quot;: {
setSelectedOption({
...option,
subOptions: option.subOptions.concat(bicepsList)
});
break;
}
default: {
setSelectedOption({
...option,
subOptions: []
});
break;
}
}
setShowOptions(false);
};

Benefit of option.subOptions.concat(anyList) is you can have default exercises from "options" state already set and append more exercies.

huangapple
  • 本文由 发表于 2023年2月16日 13:19:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/75468127.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定