如何使用 redux 分派和重用图像

How to dispatch and reuse an image with redux

我是 React Native 和 Redux 的新手,我遇到了一个问题。 我想将图像 link 发送到我的商店并重复使用此 link 以在我的主页组件中显示本地图像,问题是它不起作用。我的图像没有显示在我的模拟器中,我得到这个错误:

Warning: Failed prop type: Invalid prop "source" supplied to "Image", expected one of type [number].

我认为这个问题是因为我没有弄清楚如何在我的 home 组件中使用 require()

这是我的代码:

首先我们有我的 MachineList 组件,其中有我的对象的所有数据,包括它们的图像 link,这里图像正确显示没有问题:

const machineListData = [
    {
        id: '1',
        name: 'développé couché',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/benchPressI.jpg'),
    },
    {
        id: '2',
        name: 'presse à jambe',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/legPressI.jpg'),
    },
    {
        id: '3',
        name: 'machine dos',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/backMachineI.png'),
    }
]


const MachinesList = (props) => {


    let [fontsLoaded] = useFonts({
        Circular: require('../assets/fonts/Circular.ttf')
      });  

    function machineAction(props, item) {
        props.navigation.navigate('AddMachineDetails', {item})
    }

//I deleted some code to make it more easy to read

    function machineAction(props, item) {
        props.navigation.navigate('AddMachineDetails', {item})
    }

    return (
        <SafeAreaView style={styles.container}>
            <FlatList data={machineListData} keyExtractor={(item) => item.id} 
            renderItem={({item}) => (
                <TouchableOpacity style={styles.machineBox} onPress={() => machineAction(props, item)}>
                    <Image source={item.imageLink} style={styles.imageStyle}/>
                    <Text style={styles.machineName}>{item.name}</Text>
                </TouchableOpacity>
            )}
            />
        </SafeAreaView>
    )}
}

所以之后我使用反应导航将我的对象(用户在 flatList 中按下的对象)发送到我的 AddMachineDetailsComponent,(这里图像仍在显示)。在我的 AddMachineDetailsComponent 中,我将对象分派给 redux :

const handleAll = () => {
    let date = new Date();
    let history = {weight: machineWeight, date: date}
    const finalObject = {
      id: item.id,
      name: item.name,
      weight: machineWeight,
      notes: machineNotes,
      history: [history],
      imageLink: item.imageLink
    }
    dispatch(newmachine(finalObject))
    props.navigation.navigate("MachinesList")

  }

这是我的 initialState 在 redux 中的样子。通常 initialState 数组是空的,但我通过在 Google Chrome 的 redux devTool 中复制我的对象来检查它是否有效。 (因此您在数组中看到的对象只是我的 AddMachineDetails 发送的内容的副本。):

const initialState = [
    {
        id: '0',
        name: 'machine dos',
        weight: 54,
        notes: "Ce sont mes notes",
        history: [{weight: 54, date: "2022-02-16T09:11:44.843Z"}],
        imageLink: '/static/media/backMachineI.7b31b62c.png'
    }
]


const addMachineReducer = ( state = initialState, action) => {
    //TODO:
    //test mettre itemPosition une fois là peut être ??
    let itemPosition = state.findIndex(fPostition)

    function fPostition(place) {
        //retourne true ou false et findindex si true va donner la position
        return place.id === action.position
    }

    switch(action.type) {
        case 'NEWMACHINE': 

            //pour l'id je génére un nombre aléatoire (c'est pas le truc parfait)
            let i = Math.random()* 10000
            action.payload.id = i.toString()
            return [...state, action.payload];


        case 'UPDATEMACHINEWEIGHT':
            console.log('début')
            // let itemPosition = state.findIndex(fPostition)

            console.log('' + itemPosition)


            state[itemPosition] = {...state[itemPosition], weight: action.payload}
            return [...state];

        case 'UPDATEMACHINEHISTORY':
            const weight = action.payload.weight
            const date = action.payload.date

            state[itemPosition].history = [...state[itemPosition].history, {weight: weight, date: date}]
            return [...state]

        case 'UPDATEMACHINENOTES':

            state[itemPosition] = {...state[itemPosition], notes: action.payload}
            return [...state];
            
        default:
            return state
    }
}

export default addMachineReducer

最后是我的主页组件,我在其中收到错误:

    const machineList = useSelector(state => state.addMachine)

//I deleted some code to make it more easy to read 
 return (
            <View>
                <FlatList data={machineList} keyExtractor={(item) => item.id} renderItem={({item}) => (
                    <TouchableOpacity style={styles.machineBox} onPress={() => goToDetails(item)} onLongPress={() => deleteItem()}>
                        <Image source={item.imageLink} style={styles.image}/>
                        <Text style={styles.machineName}>{item.name}</Text>
                        <Text style={styles.machineWeight}>{item.weight}</Text>
                    </TouchableOpacity>
                )}></FlatList>
            </View>
        )

所以我得到了错误Warning: Failed prop type: Invalid prop "source" supplied to "Image", expected one of type [number]. 我想这可能与我无法在此组件中使用require()有关,但没有找到任何解决方案。 (在 home 组件中,我没有导入任何与图像路径文件相关的内容)。

不要将图像存储在状态中。直接从 machineListData 获取图像。


const machineListData = [
    {
        id: '1',
        name: 'développé couché',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/benchPressI.jpg'),
    },
    {
        id: '2',
        name: 'presse à jambe',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/legPressI.jpg'),
    },
    {
        id: '3',
        name: 'machine dos',
        poid: 0,
        notes: '',
        imageLink: require('../assets/machineListImages/backMachineI.png'),
    }
]


    const machineList = useSelector(state => state.addMachine)

//I deleted some code to make it more easy to read 
 return (
            <View>
                <FlatList data={machineList} keyExtractor={(item) => item.id} renderItem={({item}) => (
                    <TouchableOpacity style={styles.machineBox} onPress={() => goToDetails(item)} onLongPress={() => deleteItem()}>
                        <Image source={machineListData.find((data)=>item.id ===data.id).imageLink} style={styles.image}/>
                        <Text style={styles.machineName}>{item.name}</Text>
                        <Text style={styles.machineWeight}>{item.weight}</Text>
                    </TouchableOpacity>
                )}></FlatList>
            </View>
        )