Как отобразить массив одного экрана на другом в реагировать на родной? - PullRequest
0 голосов
/ 02 мая 2020

Я хочу отобразить массив subjects из SubjectsScreen в MarkAttendanceScreen как FlatList. Я пытался реализовать его с помощью Redux. Получение ошибки: typeError: undefined is not an object (evaluating 'route.params.subjects')

// reducer
function subjectsReducer(state, action) {
  if (typeof state === 'undefined') {
    return 0;
  }
  return state;
}

// store
let store = createStore(combineReducers({ subjects: subjectsReducer }));

// attendance screen
function MarkAttendanceScreen({ route }) {
  return (
    <FlatList>
      <Text style={styles.listItemCont}>{route.params.subjects}</Text>
    </FlatList>
  );
}

// subjects screen
class SubjectsScreen extends Component {
  state = {
    subjects: [],
    text: ""
  };

  changeTextHandler = text => {
    this.setState({ text: text });
  };

  addSubject = () => {
    let notEmpty = this.state.text.trim().length > 0;

    if (notEmpty) {
      this.setState(
        prevState => {
          let { subjects, text } = prevState;
          return {
            subjects: subjects.concat({ key: subjects.length, text: text }),
            text: ""
          };
        },
        () => Subjects.save(this.state.subjects)
      );
    }
  };

  deleteSubject = i => {
    this.setState(
      prevState => {
        let subjects = prevState.subjects.slice();

        subjects.splice(i, 1);

        return { subjects: subjects };
      },
      () => Subjects.save(this.state.subjects)
    );
  };

  componentDidMount() {
    Keyboard.addListener(
      isAndroid ? "keyboardDidShow" : "keyboardWillShow",
      e => this.setState({ viewPadding: e.endCoordinates.height + viewPadding })
    );

    Keyboard.addListener(
      isAndroid ? "keyboardDidHide" : "keyboardWillHide",
      () => this.setState({ viewPadding: viewPadding })
    );

    Subjects.all(subjects => this.setState({ subjects: subjects || [] }));
  }

  render() {
    return (
      <View
        style={[styles.container, { paddingBottom: this.state.viewPadding }]}
      >
        <FlatList
          style={styles.list}
          data={this.state.subjects}
          renderItem={({ item, index }) =>
            <View>
              <View style={styles.listItemCont}>
                <Text style={styles.listItem}>
                  {item.text}
                </Text>
                <View style={styles.button}>
                  <Button title="X" style={styles.button} onPress={() => this.deleteSubject(index)} color="#FFA500" />
                </View>
              </View>
              <View style={styles.hr} />
            </View>}
          keyExtractor={ (item, index) => index.toString() }
        />
        <TextInput
          style={styles.textInput}
          textAlign={'center'}
          onChangeText={this.changeTextHandler}
          onSubmitEditing={this.addSubject}

          value={this.state.text}
          placeholder="Add Subject"
          returnKeyType="done"
          returnKeyLabel="done"
        >
          <MarkAttendanceScreen subjectList={this.state.subjects} />
        </TextInput>
      </View>
    );
  }
}

let Subjects = {
  convertToArrayOfObject(subjects, callback) {
    return callback(
      subjects ? subjects.split("||").map((subject, i) => ({ key: i, text: subject })) : []
    );
  },
  convertToStringWithSeparators(subjects) {
    return subjects.map(subject => subject.text).join("||");
  },
  all(callback) {
    return AsyncStorage.getItem("SUBJECTS", (err, subjects) =>
      this.convertToArrayOfObject(subjects, callback)
    );
  },
  save(subjects) {
    AsyncStorage.setItem("SUBJECTS", this.convertToStringWithSeparators(subjects));
  }
};

// Connect the screens to Redux
let subjectsContainer = connect(state => ({ subjectsList: state.subjectsList }))(SubjectsScreen);

const MarkAttendanceStack = createStackNavigator();
const SubjectsStack = createStackNavigator();

function MarkAttendanceStackScreen() {
  return (
    <MarkAttendanceStack.Navigator>
      <MarkAttendanceStack.Screen name="Mark Attendance" component={MarkAttendanceScreen} options={({ route }) => ({ title: route.params.subjectsList })} />
    </MarkAttendanceStack.Navigator>
  );
}

function SubjectsStackScreen() {
  return (
    <SubjectsStack.Navigator>
      <SubjectsStack.Screen name="Subjects" component={subjectsContainer} />
    </SubjectsStack.Navigator>
  );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...