如何将此类代码转换为钩子? -反应性

时间:2020-04-06 00:06:28

标签: javascript reactjs react-native

我正在尝试将此类React Component转换为React Hooks。我已经测试了代码并且可以正常工作,但是现在我想使用钩子来完成它,问题是我不完全了解该怎么做,我试图去做,但是它根本不起作用,我认为每个this.variablename都应更改为setvariablename,但我无法使其正常工作。

我可以帮忙吗?非常感谢。

我正在使用这个库react-native-image-crop-picker

    export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      fileList:[]
    }
  }

onSelectedImage = (image) => {
  let newDataImg = this.state.fileList;
  const source = {uri: image.path};
  let item = {
    id: Date.now(),
    url: source,
    content: image.data
  };
  newDataImg.push(item);
  this.setState({fileList: newDataImg})
};

  takePhotoFromCamera = () => {
    ImagePicker.openCamera({
      width: 300,
      height: 400,
      cropping: true,
    }).then(image => {
      this.onSelectedImage(image);
      console.log(image);
    });
  };
  choosePhotoFromLibrary = () => {
    ImagePicker.openPicker({
      width: 300,
      height: 400,
      cropping: true
    }).then(image => {
      this.onSelectedImage(image);
      console.log(image);
    });
  };

renderItem = ({item, index}) =>{
  return(
    <View>
      <Image source={item.url} style={styles.itemImage} />
    </View>
  )
};

render() {
  let {fileList}= this.state;
  return (
    <View style={styles.container}>
        <FlatList
          data={fileList}
          keyExtractor = {(item, index) => index.toString() }
          renderItem={this.renderItem}
          extraData={this.state}
        />

        <TouchableOpacity  style={styles.viewData} onPress={this.takePhotoFromCamera}>
          <text>Foto</text>
        </TouchableOpacity>

        <TouchableOpacity  style={styles.viewData} onPress={this.choosePhotoFromLibrary}>
          <text>galeria</text>
        </TouchableOpacity>

    </View>
  );
};
}

2 个答案:

答案 0 :(得分:1)

export default function App(props) {

const [fileList, setFileList] = React.useState([]);

const onSelectedImage = (image) => {
 let newDataImg fileList;
 const source = {uri: image.path};
 let item = {
   id: Date.now(),
   url: source,
   content: image.data
 };
 newDataImg.push(item);
 setFileList(newDataImg)
};

const takePhotoFromCamera = () => {
   ImagePicker.openCamera({
     width: 300,
     height: 400,
     cropping: true,
   }).then(image => {
     onSelectedImage(image);
     console.log(image);
   });
 };
 const choosePhotoFromLibrary = () => {
   ImagePicker.openPicker({
     width: 300,
     height: 400,
     cropping: true
   }).then(image => {
     onSelectedImage(image);
     console.log(image);
   });
 };

const renderItem = ({item, index}) =>{
 return(
   <View>
     <Image source={item.url} style={styles.itemImage} />
   </View>
 )
};

 return (
   <View style={styles.container}>
       <FlatList
         data={fileList}
         keyExtractor = {(item, index) => index.toString() }
         renderItem={renderItem}
         extraData={{ fileList }}
       />

       <TouchableOpacity  style={styles.viewData} onPress={takePhotoFromCamera}>
         <text>Foto</text>
       </TouchableOpacity>

       <TouchableOpacity  style={styles.viewData} onPress={choosePhotoFromLibrary}>
         <text>galeria</text>
       </TouchableOpacity>

   </View>
 );
};

答案 1 :(得分:1)

改进了devcass的答案,使用useCallback()来正确地记录回调,并避免将对象文字传递给子组件(例如extraData={{ fileList }}),并使用回调签名对状态变量进行不可变的更新之setState()

import { useState, useMemo, useCallback } from 'react';

export default function App(props) {
  const [fileList, setFileList] = useState([]);
  const state = useMemo(() => ({ fileList }), [fileList]);

  const onSelectedImage = useCallback((image) => {
    setFileList(fileList => {
      const newDataImg = [...fileList];
      const source = { uri: image.path };
      const item = {
        id: Date.now(),
        url: source,
        content: image.data
      };
      newDataImg.push(item);
      return newDataImg;
    });
  }, [setFileList]);

  const takePhotoFromCamera = useCallback(() => {
    ImagePicker.openCamera({
      width: 300,
      height: 400,
      cropping: true,
    }).then(image => {
      onSelectedImage(image);
      console.log(image);
    });
  }, [onSelectedImage]);

  const choosePhotoFromLibrary = useCallback(() => {
    ImagePicker.openPicker({
      width: 300,
      height: 400,
      cropping: true
    }).then(image => {
      onSelectedImage(image);
      console.log(image);
    });
  }, [onSelectedImage]);

  const renderItem = useCallback(({ item, index }) => {
    return (
      <View>
        <Image source={item.url} style={styles.itemImage} />
      </View>
    );
  }, []);

  return (
    <View style={styles.container}>
      <FlatList
        data={fileList}
        keyExtractor={(item, index) => index.toString()}
        renderItem={renderItem}
        extraData={state}
      />

      <TouchableOpacity style={styles.viewData} onPress={takePhotoFromCamera}>
        <text>Foto</text>
      </TouchableOpacity>

      <TouchableOpacity style={styles.viewData} onPress={choosePhotoFromLibrary}>
        <text>galeria</text>
      </TouchableOpacity>
    </View>
  );
}